diff --git a/check/instance/pom.xml b/check/instance/pom.xml new file mode 100644 index 0000000..cc337f2 --- /dev/null +++ b/check/instance/pom.xml @@ -0,0 +1,30 @@ + + + + 4.0.0 + + org.eclipse.daanse + org.eclipse.daanse.olap.check + ${revision} + + org.eclipse.daanse.olap.check.instance + Daanse Model Check Instance + Daanse Model Check Instance + pom + + tutorial + serializer + + diff --git a/check/instance/serializer/.gitignore b/check/instance/serializer/.gitignore new file mode 100644 index 0000000..ebfe9f3 --- /dev/null +++ b/check/instance/serializer/.gitignore @@ -0,0 +1 @@ +/daansetutorials/ diff --git a/check/instance/serializer/pom.xml b/check/instance/serializer/pom.xml new file mode 100644 index 0000000..37762d7 --- /dev/null +++ b/check/instance/serializer/pom.xml @@ -0,0 +1,61 @@ + + + + 4.0.0 + + org.eclipse.daanse + org.eclipse.daanse.olap.check.instance + ${revision} + + org.eclipse.daanse.olap.check.instance.serializer + + + 6.2.0 + 2.30.0 + 2.36.0 + 2.37.0 + + + + + org.eclipse.daanse + org.eclipse.daanse.olap.check.model.emf + ${project.version} + compile + + + org.geckoprojects.emf.utils + org.gecko.emf.json + 1.5.1 + compile + + + + org.eclipse.emf + org.eclipse.emf.common + ${emf.common.version} + test + + + + + org.eclipse.daanse + org.eclipse.daanse.olap.check.instance.tutorial.access.cataloggrand + ${project.version} + + + + + diff --git a/check/instance/serializer/src/test/java/org/eclipse/daanse/olap/check/instance/serializer/ResourceSetWriteReadTest.java b/check/instance/serializer/src/test/java/org/eclipse/daanse/olap/check/instance/serializer/ResourceSetWriteReadTest.java new file mode 100644 index 0000000..0cb3cc9 --- /dev/null +++ b/check/instance/serializer/src/test/java/org/eclipse/daanse/olap/check/instance/serializer/ResourceSetWriteReadTest.java @@ -0,0 +1,295 @@ +/* +* Copyright (c) 2025 Contributors to the Eclipse Foundation. +* +* This program and the accompanying materials are made +* available under the terms of the Eclipse Public License 2.0 +* which is available at https://www.eclipse.org/legal/epl-2.0/ +* +* SPDX-License-Identifier: EPL-2.0 +* +* Contributors: +* SmartCity Jena - initial +* Stefan Bischof (bipolis.org) - initial +*/ +package org.eclipse.daanse.olap.check.instance.serializer; + +import java.io.ByteArrayOutputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.sql.SQLException; +import java.util.Comparator; +import java.util.Dictionary; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import org.eclipse.daanse.olap.check.model.check.OlapCheckModel; +import org.eclipse.daanse.olap.check.model.check.OlapCheckPackage; +import org.eclipse.daanse.olap.check.model.provider.CatalogCheckSupplier; +import org.eclipse.emf.common.util.TreeIterator; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.xmi.XMLResource; +import org.gecko.emf.osgi.annotation.require.RequireEMF; +import org.gecko.emf.osgi.constants.EMFNamespaces; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; +import org.osgi.test.common.annotation.InjectBundleContext; +import org.osgi.test.common.annotation.InjectService; +import org.osgi.test.common.service.ServiceAware; +import org.osgi.test.junit5.cm.ConfigurationExtension; +import org.osgi.test.junit5.context.BundleContextExtension; +import org.osgi.test.junit5.service.ServiceExtension; + +@ExtendWith(BundleContextExtension.class) +@ExtendWith(ServiceExtension.class) +@ExtendWith(ConfigurationExtension.class) +@RequireEMF +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class ResourceSetWriteReadTest { + + static int i = 0; + static Path tempDir; + + @BeforeAll + public static void beforeAll() throws IOException { + tempDir = Path.of("./daansetutorials"); + deleteDirectory(tempDir); + tempDir = Files.createDirectories(tempDir); + } + + @Test + @Order(1) + public void writePopulation(@InjectBundleContext BundleContext bc, + @InjectService(cardinality = 1, filter = "(" + EMFNamespaces.EMF_MODEL_NAME + "=" + + "model" + ")") ResourceSet resourceSet, + @InjectService ServiceAware mappingSuppiersSA) + throws SQLException, InterruptedException, IOException { + + try { + + List> srs = mappingSuppiersSA.getServiceReferences(); + + // Create combined ZIP directory structure + Path zipDir = Files.createDirectories(tempDir.resolve("cubeserver/tutorial/zip")); + ZipOutputStream combinedZos = new ZipOutputStream(new FileOutputStream(zipDir.resolve("all-tutorials.zip").toFile())); + + srs.sort((o1, o2) -> { + Object s1 = o1.getProperty("number"); + Object s2 = o2.getProperty("number"); + + String ss1 = s1 == null ? "9999.9.9" : s1.toString(); + String ss2 = s2 == null ? "9999.9.9" : s2.toString(); + return ss1.compareToIgnoreCase(ss2); + }); + for (ServiceReference sr : srs) { + + try { + CatalogCheckSupplier catalogMappingSupplier = mappingSuppiersSA.getService(sr); + + serializeCatalog(resourceSet, catalogMappingSupplier, sr.getProperties(), combinedZos); + } catch (Exception e) { + e.printStackTrace(); + } + } + + // Close combined ZIP + combinedZos.close(); + + } catch (Exception e) { + e.printStackTrace(); + } + + } + + private void serializeCatalog(ResourceSet resourceSet, + CatalogCheckSupplier catalogMappingSupplier, Dictionary dictionary, ZipOutputStream combinedZos) throws IOException { + + String name = catalogMappingSupplier.getClass().getPackageName(); + name = name.substring(46); + + Path zipDir = Files.createDirectories(tempDir.resolve("cubeserver/tutorial/zip")); + ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipDir.resolve(name + ".zip").toFile())); + + Bundle b = FrameworkUtil.getBundle(catalogMappingSupplier.getClass()); + + OlapCheckModel cm = catalogMappingSupplier.get(); + + + + String grp = (String) dictionary.get("group"); + grp = grp == null ? "Unstrutured" : grp; + + String catName = cm.getName(); + + catName = catName.replaceFirst(grp + " - ", "").replaceFirst("Daanse Tutorial - ", ""); + + + String kind = (String) dictionary.get("kind"); + kind = kind == null ? "other" : kind; + + String nr = (String) dictionary.get("number"); + nr = nr == null ? "z" + i : nr; + + OlapCheckModel c = cm; + + URI uriCatalog = URI.createFileURI("catalog.xmi"); + Resource resourceCatalog = resourceSet.createResource(uriCatalog); + + Set set = new HashSet<>(); + + set = allRef(set, c); + + // sort + + List sortedList = set.stream().sorted(comparator).toList(); + + + for (EObject eObject : sortedList) { + + if (eObject.eContainer() == null) { + resourceCatalog.getContents().add(eObject); + } + + } + Map options = new HashMap<>(); + options.put(XMLResource.OPTION_ENCODING, "UTF-8"); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + resourceCatalog.save(baos, options); + + ZipEntry entry = new ZipEntry(name + "/mapping/catalog.xmi"); + zos.putNextEntry(entry); + zos.write(baos.toByteArray()); + zos.closeEntry(); + + // Add to combined ZIP + ZipEntry combinedEntry = new ZipEntry(name + "/mapping/catalog.xmi"); + combinedZos.putNextEntry(combinedEntry); + combinedZos.write(baos.toByteArray()); + combinedZos.closeEntry(); + + Files.createDirectories(zipDir); + + zos.close(); + } + + private Set allRef(Set set, EObject eObject) { + + if (set.add(eObject)) { + + TreeIterator allContents = eObject.eAllContents(); + while (allContents.hasNext()) { + EObject obj = allContents.next(); + + set = allRef(set, obj); + } + + for (EObject eObject2 : eObject.eCrossReferences()) { + + set = allRef(set, eObject2); + + } + EObject eContainer = eObject.eContainer(); + + if (eContainer != null) { + set = allRef(set, eContainer); + + } + + } + return set; + } + + static EObjectComparator comparator = new EObjectComparator(); + + static class EObjectComparator implements Comparator { + + AtomicInteger COUNTER = new AtomicInteger(1); + Map map = new HashMap(); + + EObjectComparator() { + add(OlapCheckPackage.Literals.CATALOG_CHECK); + add(OlapCheckPackage.Literals.DATABASE_SCHEMA_CHECK); + add(OlapCheckPackage.Literals.CUBE_CHECK); + } + + void add(EClass eClass) { + map.put(eClass, COUNTER.incrementAndGet()); + } + + @Override + public int compare(EObject o1, EObject o2) { + + EClass eClass1 = o1.eClass(); + EClass eClass2 = o2.eClass(); + int value = map.getOrDefault(eClass1, 0) - map.getOrDefault(eClass2, 0); + + if (value != 0) { + return value; + } + + Object s1 = ""; + Object s2 = ""; + EStructuralFeature eStructuralFeature1 = eClass1.getEStructuralFeature("id"); + if (eStructuralFeature1 != null) { + + s1 = o1.eGet(eStructuralFeature1); + } + EStructuralFeature eStructuralFeature2 = eClass2.getEStructuralFeature("id"); + if (eStructuralFeature2 != null) { + + s2 = o2.eGet(eStructuralFeature2); + } + if (s1 == null) { + s1 = ""; + } + if (s2 == null) { + s2 = ""; + } + + return s1.toString().compareToIgnoreCase(s2.toString()); + } + }; + + public static void deleteDirectory(Path directory) throws IOException { + if (!Files.exists(directory)) { + return; + } + + Files.walkFileTree(directory, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + Files.delete(file); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + Files.delete(dir); + return FileVisitResult.CONTINUE; + } + }); + } +} diff --git a/check/instance/serializer/test.bndrun b/check/instance/serializer/test.bndrun new file mode 100644 index 0000000..ba7bbe9 --- /dev/null +++ b/check/instance/serializer/test.bndrun @@ -0,0 +1,80 @@ +#******************************************************************************* +# Copyright (c) 2025 Contributors to the Eclipse Foundation +# +# This program and the accompanying materials are made +# available under the terms of the Eclipse Public License 2.0 +# which is available at https://www.eclipse.org/legal/epl-2.0/ +# +# SPDX-License-Identifier: EPL-2.0 +# +# Contributors: +# SmartCity Jena - initial +# Stefan Bischof (bipolis.org) - initial +#******************************************************************************* + +-runstartlevel: \ + order=sortbynameversion,\ + begin=-1 + +-runtrace: true + +-tester: biz.aQute.tester.junit-platform + +# JaCoCo calculates test coverage +-runpath.jacoco:\ + org.jacoco.agent,\ + org.jacoco.agent.rt + +-runvm.coverage: -javaagent:${repo;org.jacoco.agent.rt}=destfile=${target-dir}/jacoco.exec +-runvm.base: -DbasePath=${.} + +-runpath.log: \ + ch.qos.logback.classic,\ + ch.qos.logback.core,\ + slf4j.api + +-runproperties.logback:\ + org.osgi.framework.bootdelegation=org.mockito.internal.creation.bytebuddy.inject,\ + logback.configurationFile=${project.build.testOutputDirectory}/logback-test.xml + +-runsystemcapabilities: ${native_capability} + +-resolve.effective: active + + +-runfw: org.apache.felix.framework + +-runee: JavaSE-21 + +-runrequires: \ + bnd.identity;id='${project.artifactId}-tests',\ + bnd.identity;id='${project.artifactId}',\ + bnd.identity;id='org.eclipse.daanse.olap.check.instance.tutorial.access.cataloggrand' +# -runbundles is calculated by the bnd-resolver-maven-plugin + +-runbundles: \ + junit-jupiter-api;version='[5.10.2,5.10.3)',\ + junit-jupiter-engine;version='[5.10.2,5.10.3)',\ + junit-jupiter-params;version='[5.10.2,5.10.3)',\ + junit-platform-commons;version='[1.10.2,1.10.3)',\ + junit-platform-engine;version='[1.10.2,1.10.3)',\ + junit-platform-launcher;version='[1.10.2,1.10.3)',\ + org.apache.felix.configadmin;version='[1.9.26,1.9.27)',\ + org.apache.felix.scr;version='[2.2.10,2.2.11)',\ + org.eclipse.daanse.olap.check.instance.serializer;version='[0.0.1,0.0.2)',\ + org.eclipse.daanse.olap.check.instance.serializer-tests;version='[0.0.1,0.0.2)',\ + org.eclipse.daanse.olap.check.instance.tutorial.access.cataloggrand;version='[0.0.1,0.0.2)',\ + org.eclipse.daanse.olap.check.model.emf;version='[0.0.1,0.0.2)',\ + org.eclipse.emf.common;version='[2.30.0,2.30.1)',\ + org.eclipse.emf.ecore;version='[2.36.0,2.36.1)',\ + org.eclipse.emf.ecore.xmi;version='[2.37.0,2.37.1)',\ + org.gecko.emf.osgi.component;version='[6.2.0,6.2.1)',\ + org.opentest4j;version='[1.3.0,1.3.1)',\ + org.osgi.service.cm;version='[1.6.1,1.6.2)',\ + org.osgi.service.component;version='[1.5.1,1.5.2)',\ + org.osgi.test.common;version='[1.3.0,1.3.1)',\ + org.osgi.test.junit5;version='[1.3.0,1.3.1)',\ + org.osgi.test.junit5.cm;version='[1.3.0,1.3.1)',\ + org.osgi.util.converter;version='[1.0.9,1.0.10)',\ + org.osgi.util.function;version='[1.2.0,1.2.1)',\ + org.osgi.util.promise;version='[1.3.0,1.3.1)' \ No newline at end of file diff --git a/check/instance/tutorial/access/cataloggrand/pom.xml b/check/instance/tutorial/access/cataloggrand/pom.xml new file mode 100644 index 0000000..10768bc --- /dev/null +++ b/check/instance/tutorial/access/cataloggrand/pom.xml @@ -0,0 +1,31 @@ + + + + 4.0.0 + + org.eclipse.daanse + org.eclipse.daanse.olap.check.instance.tutorial.access + ${revision} + + org.eclipse.daanse.olap.check.instance.tutorial.access.cataloggrand + + + + org.eclipse.daanse + org.eclipse.daanse.olap.check.model.emf + ${revision} + compile + + + + \ No newline at end of file diff --git a/check/instance/tutorial/access/cataloggrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/cataloggrand/CatalogCheckSupplier.java b/check/instance/tutorial/access/cataloggrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/cataloggrand/CatalogCheckSupplier.java new file mode 100644 index 0000000..4a65143 --- /dev/null +++ b/check/instance/tutorial/access/cataloggrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/cataloggrand/CatalogCheckSupplier.java @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.instance.tutorial.access.cataloggrand; +import org.eclipse.daanse.olap.check.model.check.CatalogCheck; +import org.eclipse.daanse.olap.check.model.check.CubeAttribute; +import org.eclipse.daanse.olap.check.model.check.CubeAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.CubeCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnAttribute; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseSchemaCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseTableCheck; +import org.eclipse.daanse.olap.check.model.check.DimensionAttribute; +import org.eclipse.daanse.olap.check.model.check.DimensionAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.DimensionCheck; +import org.eclipse.daanse.olap.check.model.check.HierarchyAttribute; +import org.eclipse.daanse.olap.check.model.check.HierarchyAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.HierarchyCheck; +import org.eclipse.daanse.olap.check.model.check.LevelCheck; +import org.eclipse.daanse.olap.check.model.check.MatchMode; +import org.eclipse.daanse.olap.check.model.check.MeasureAttribute; +import org.eclipse.daanse.olap.check.model.check.MeasureAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.MeasureCheck; +import org.eclipse.daanse.olap.check.model.check.OlapCheckFactory; +import org.eclipse.daanse.olap.check.model.check.OlapCheckModel; +import org.eclipse.daanse.olap.check.model.check.QueryCheck; +import org.eclipse.daanse.olap.check.model.check.QueryLanguage; +import org.eclipse.daanse.olap.check.model.check.RoleCheck; +import org.osgi.service.component.annotations.Component; + +@Component(service = CatalogCheckSupplier.class) +public class CatalogCheckSupplier implements org.eclipse.daanse.olap.check.model.provider.CatalogCheckSupplier { + private static final OlapCheckFactory FACTORY = OlapCheckFactory.eINSTANCE; + + @Override + public OlapCheckModel get() { + OlapCheckModel model = FACTORY.createOlapCheckModel(); + model.setName("Access Catalog Gran Catalog Checks"); + model.setDescription("Comprehensive checks for Access Catalog Gran catalog - logistics and package delivery analysis"); + //ConnectionConfig connectionConfig = FACTORY.createConnectionConfig(); + //connectionConfig.setCatalogName("Daanse Tutorial - Access Catalog Gran"); + //connectionConfig.getRoles().add("role1"); + //model.setConnectionConfig(connectionConfig); + // Create catalog check + CatalogCheck catalogCheck = FACTORY.createCatalogCheck(); + catalogCheck.setName("Catalog Check"); + catalogCheck.setDescription("Demonstrates access control with catalog grants and roles"); + catalogCheck.setCatalogName("Daanse Tutorial - Access Catalog Gran"); + catalogCheck.setEnabled(true); + // Add database schema check with detailed column checks + catalogCheck.getDatabaseSchemaChecks().add(createDatabaseSchemaCheck()); + // Add cube check + catalogCheck.getCubeChecks().add(createCubeCheck()); + // Add role check + RoleCheck roleAllCheck = FACTORY.createRoleCheck(); + roleAllCheck.setName("roleAll Check"); + roleAllCheck.setRoleName("roleAll"); + catalogCheck.getRoleChecks().add(roleAllCheck); + + RoleCheck roleAllDimWithCubeGrandCheck = FACTORY.createRoleCheck(); + roleAllDimWithCubeGrandCheck.setName("roleAllDimWithCubeGrand Check"); + roleAllDimWithCubeGrandCheck.setRoleName("roleAllDimWithCubeGrand"); + catalogCheck.getRoleChecks().add(roleAllDimWithCubeGrandCheck); + + RoleCheck roleNoneCheck = FACTORY.createRoleCheck(); + roleNoneCheck.setName("roleNone Check"); + roleNoneCheck.setRoleName("roleNone"); + catalogCheck.getRoleChecks().add(roleNoneCheck); + + // Add query checks at catalog level + catalogCheck.getQueryChecks().addAll(java.util.List.of( + createQueryCheckForRoleAll(), + createQueryCheckForRoleAllDimWithCubeGrand(), + createQueryCheckForRoleNone() + )); + model.getCatalogChecks().add(catalogCheck); + return model; + } + + private DatabaseSchemaCheck createDatabaseSchemaCheck() { + DatabaseSchemaCheck schemaCheck = FACTORY.createDatabaseSchemaCheck(); + schemaCheck.setName("Daanse Tutorial - Access Catalog Grand Database Schema Check"); + schemaCheck.setDescription("Verify database tables and columns exist for Daanse Tutorial - Access Catalog Grand"); + schemaCheck.setEnabled(true); + // Check parcels fact table with columns + DatabaseTableCheck factTableCheck = FACTORY.createDatabaseTableCheck(); + factTableCheck.setTableName("Fact"); + factTableCheck.setEnabled(true); + // Add column checks for Fact table + factTableCheck.getColumnChecks().add(createColumnCheck("KEY", "VARCHAR")); + factTableCheck.getColumnChecks().add(createColumnCheck("VALUE", "INTEGER")); + schemaCheck.getTableChecks().add(factTableCheck); + return schemaCheck; + } + private DatabaseColumnCheck createColumnCheck(String columnName, String type) { + DatabaseColumnCheck columnCheck = FACTORY.createDatabaseColumnCheck(); + columnCheck.setName(columnName + " Column Check"); + columnCheck.setColumnName(columnName); + DatabaseColumnAttributeCheck typeCheck = FACTORY.createDatabaseColumnAttributeCheck(); + typeCheck.setAttributeType(DatabaseColumnAttribute.TYPE); + typeCheck.setExpectedValue(type); + columnCheck.getColumnAttributeChecks().add(typeCheck); + columnCheck.setEnabled(true); + return columnCheck; + } + private CubeCheck createCubeCheck() { + CubeCheck cubeCheck = FACTORY.createCubeCheck(); + cubeCheck.setName("Access Catalog Grant Cube Check"); + cubeCheck.setDescription("Verify Access Catalog Gran cube structure with all dimensions and measures"); + cubeCheck.setCubeName("Cube1"); + cubeCheck.setEnabled(true); + // Add cube attribute checks + CubeAttributeCheck visibleCheck = FACTORY.createCubeAttributeCheck(); + visibleCheck.setName("Cube Visibility Check"); + visibleCheck.setAttributeType(CubeAttribute.VISIBLE); + visibleCheck.setExpectedBoolean(true); + + cubeCheck.getCubeAttributeChecks().add(visibleCheck); + // Add dimension checks + cubeCheck.getDimensionChecks().add(createDimensionCheck("Dimension1", null)); + // Add measure checks + cubeCheck.getMeasureChecks().add(createMeasureCheck("Measure1", "sum")); + return cubeCheck; + } + private DimensionCheck createDimensionCheck(String dimensionName, String description) { + DimensionCheck dimCheck = FACTORY.createDimensionCheck(); + dimCheck.setName(dimensionName + " Dimension Check"); + dimCheck.setDescription(description); + dimCheck.setDimensionName(dimensionName); + dimCheck.setEnabled(true); + + DimensionAttributeCheck visibleCheck = FACTORY.createDimensionAttributeCheck(); + visibleCheck.setName(dimensionName + " Visible Check"); + visibleCheck.setAttributeType(DimensionAttribute.VISIBLE); + visibleCheck.setExpectedBoolean(true); + dimCheck.getDimensionAttributeChecks().add(visibleCheck); + + HierarchyCheck hierarchyCheck = FACTORY.createHierarchyCheck(); + hierarchyCheck.setName("Hierarchy1 Hierarchy Check"); + hierarchyCheck.setEnabled(true); + hierarchyCheck.setHierarchyName("Hierarchy1"); + + HierarchyAttributeCheck hasAllCheck = FACTORY.createHierarchyAttributeCheck(); + hasAllCheck.setName("Hierarchy1 HasAll Check"); + hasAllCheck.setAttributeType(HierarchyAttribute.HAS_ALL); + hasAllCheck.setExpectedBoolean(false); + hierarchyCheck.getHierarchyAttributeChecks().add(hasAllCheck); + + LevelCheck levelCheck = FACTORY.createLevelCheck(); + levelCheck.setName("Level1 Level Check"); + levelCheck.setLevelName("Level1"); + levelCheck.setDescription("Verify level Level1 exists"); + levelCheck.setEnabled(true); + + //LevelAttributeCheck levelAttributeCheck = FACTORY.createLevelAttributeCheck(); + //TODO add column type + //levelCheck.getLevelAttributeChecks().add(levelAttributeCheck); + + hierarchyCheck.getLevelChecks().add(levelCheck); + dimCheck.getHierarchyChecks().add(hierarchyCheck); + + return dimCheck; + } + + private MeasureCheck createMeasureCheck(String measureName, String expectedAggregator) { + MeasureCheck measureCheck = FACTORY.createMeasureCheck(); + measureCheck.setName(measureName + " Measure Check"); + measureCheck.setMeasureName(measureName); + measureCheck.setEnabled(true); + MeasureAttributeCheck visibleCheck = FACTORY.createMeasureAttributeCheck(); + visibleCheck.setName(measureName + " Visible Check"); + visibleCheck.setAttributeType(MeasureAttribute.VISIBLE); + visibleCheck.setExpectedBoolean(true); + measureCheck.getMeasureAttributeChecks().add(visibleCheck); + MeasureAttributeCheck aggregatorCheck = FACTORY.createMeasureAttributeCheck(); + aggregatorCheck.setName(measureName + " Aggregator Check"); + aggregatorCheck.setAttributeType(MeasureAttribute.AGGREGATOR); + aggregatorCheck.setExpectedValue(expectedAggregator); + aggregatorCheck.setMatchMode(MatchMode.EQUALS); + aggregatorCheck.setCaseSensitive(false); + measureCheck.getMeasureAttributeChecks().add(aggregatorCheck); + return measureCheck; + } + private QueryCheck createQueryCheckForRoleAll() { + QueryCheck queryCheck = FACTORY.createQueryCheck(); + queryCheck.setName("Measure Query Check"); + queryCheck.setDescription("Verify MDX query returns Measure data"); + queryCheck.setQuery("SELECT FROM [Cube1] WHERE ([Measures].[Measure1])"); + queryCheck.setQueryLanguage(QueryLanguage.MDX); + queryCheck.setExpectedColumnCount(1); + queryCheck.setEnabled(true); + queryCheck.getRoles().add("roleAll"); + return queryCheck; + } + + private QueryCheck createQueryCheckForRoleAllDimWithCubeGrand() { + QueryCheck queryCheck = FACTORY.createQueryCheck(); + queryCheck.setName("Measure Query Check"); + queryCheck.setDescription("Verify MDX query returns Measure data"); + queryCheck.setQuery("SELECT FROM [Cube1] WHERE ([Measures].[Measure1])"); + queryCheck.setQueryLanguage(QueryLanguage.MDX); + queryCheck.setExpectedColumnCount(1); + queryCheck.setEnabled(true); + queryCheck.getRoles().add("roleAllDimWithCubeGrand"); + return queryCheck; + } + + private QueryCheck createQueryCheckForRoleNone() { + QueryCheck queryCheck = FACTORY.createQueryCheck(); + queryCheck.setName("Measure Query Check"); + queryCheck.setDescription("Verify MDX query returns Measure data"); + queryCheck.setQuery("SELECT FROM [Cube1] WHERE ([Measures].[Measure1])"); + queryCheck.setQueryLanguage(QueryLanguage.MDX); + queryCheck.setExpectedColumnCount(0); + queryCheck.setEnabled(true); + queryCheck.getRoles().add("roleNone"); + return queryCheck; + } + +} diff --git a/check/instance/tutorial/access/cataloggrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/cataloggrand/package-info.java b/check/instance/tutorial/access/cataloggrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/cataloggrand/package-info.java new file mode 100644 index 0000000..08ab7ca --- /dev/null +++ b/check/instance/tutorial/access/cataloggrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/cataloggrand/package-info.java @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * + */ +@org.osgi.annotation.bundle.Export +@org.osgi.annotation.versioning.Version("0.0.1") +package org.eclipse.daanse.olap.check.instance.tutorial.access.cataloggrand; diff --git a/check/instance/tutorial/access/columngrand/pom.xml b/check/instance/tutorial/access/columngrand/pom.xml new file mode 100644 index 0000000..28327c5 --- /dev/null +++ b/check/instance/tutorial/access/columngrand/pom.xml @@ -0,0 +1,31 @@ + + + + 4.0.0 + + org.eclipse.daanse + org.eclipse.daanse.olap.check.instance.tutorial.access + ${revision} + + org.eclipse.daanse.olap.check.instance.tutorial.access.columngrand + + + + org.eclipse.daanse + org.eclipse.daanse.olap.check.model.emf + ${revision} + compile + + + + \ No newline at end of file diff --git a/check/instance/tutorial/access/columngrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/columngrand/CatalogCheckSupplier.java b/check/instance/tutorial/access/columngrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/columngrand/CatalogCheckSupplier.java new file mode 100644 index 0000000..19541b5 --- /dev/null +++ b/check/instance/tutorial/access/columngrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/columngrand/CatalogCheckSupplier.java @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.instance.tutorial.access.columngrand; +import org.eclipse.daanse.olap.check.model.check.CatalogCheck; +import org.eclipse.daanse.olap.check.model.check.CubeAttribute; +import org.eclipse.daanse.olap.check.model.check.CubeAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.CubeCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnAttribute; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseSchemaCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseTableCheck; +import org.eclipse.daanse.olap.check.model.check.MatchMode; +import org.eclipse.daanse.olap.check.model.check.MeasureAttribute; +import org.eclipse.daanse.olap.check.model.check.MeasureAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.MeasureCheck; +import org.eclipse.daanse.olap.check.model.check.OlapCheckFactory; +import org.eclipse.daanse.olap.check.model.check.OlapCheckModel; +import org.eclipse.daanse.olap.check.model.check.QueryCheck; +import org.eclipse.daanse.olap.check.model.check.QueryLanguage; +import org.eclipse.daanse.olap.check.model.check.RoleCheck; +import org.osgi.service.component.annotations.Component; + +@Component(service = CatalogCheckSupplier.class) +public class CatalogCheckSupplier implements org.eclipse.daanse.olap.check.model.provider.CatalogCheckSupplier { + private static final OlapCheckFactory FACTORY = OlapCheckFactory.eINSTANCE; + + @Override + public OlapCheckModel get() { + OlapCheckModel model = FACTORY.createOlapCheckModel(); + model.setName("Daanse Tutorial - Access Column Grant Checks"); + model.setDescription("Comprehensive checks for Daanse Tutorial - Access Column Grant catalog"); + //ConnectionConfig connectionConfig = FACTORY.createConnectionConfig(); + //connectionConfig.setCatalogName("Daanse Tutorial - Access Catalog Gran"); + //connectionConfig.getRoles().add("role1"); + //model.setConnectionConfig(connectionConfig); + // Create catalog check + CatalogCheck catalogCheck = FACTORY.createCatalogCheck(); + catalogCheck.setName("Daanse Tutorial - Access Column Grant Check"); + catalogCheck.setDescription("Demonstrates access control with column grant and roles"); + catalogCheck.setCatalogName("Daanse Tutorial - Access Column Grant"); + catalogCheck.setEnabled(true); + // Add database schema check with detailed column checks + catalogCheck.getDatabaseSchemaChecks().add(createDatabaseSchemaCheck()); + // Add cube check + catalogCheck.getCubeChecks().add(createCubeCheck()); + + // Add role check + RoleCheck roleAllCheck = FACTORY.createRoleCheck(); + roleAllCheck.setName("roleAll Check"); + roleAllCheck.setRoleName("roleAll"); + catalogCheck.getRoleChecks().add(roleAllCheck); + + RoleCheck roleNoneCheck = FACTORY.createRoleCheck(); + roleNoneCheck.setName("roleNone Check"); + roleNoneCheck.setRoleName("roleNone"); + catalogCheck.getRoleChecks().add(roleNoneCheck); + + // Add query checks at catalog level + catalogCheck.getQueryChecks().addAll(java.util.List.of( + createQueryCheckForRoleAll() + //createQueryCheckForRoleNone() + )); + model.getCatalogChecks().add(catalogCheck); + return model; + } + + private DatabaseSchemaCheck createDatabaseSchemaCheck() { + DatabaseSchemaCheck schemaCheck = FACTORY.createDatabaseSchemaCheck(); + schemaCheck.setName("Daanse Tutorial - Access Column Grand Database Schema Check"); + schemaCheck.setDescription("Verify database tables and columns exist for Daanse Tutorial - Access Column Grand"); + schemaCheck.setEnabled(true); + // Check parcels fact table with columns + DatabaseTableCheck factTableCheck = FACTORY.createDatabaseTableCheck(); + factTableCheck.setTableName("Fact"); + factTableCheck.setEnabled(true); + // Add column checks for Fact table + factTableCheck.getColumnChecks().add(createColumnCheck("KEY", "VARCHAR")); + factTableCheck.getColumnChecks().add(createColumnCheck("VALUE", "INTEGER")); + schemaCheck.getTableChecks().add(factTableCheck); + return schemaCheck; + } + private DatabaseColumnCheck createColumnCheck(String columnName, String type) { + DatabaseColumnCheck columnCheck = FACTORY.createDatabaseColumnCheck(); + columnCheck.setName(columnName + " Column Check"); + columnCheck.setColumnName(columnName); + DatabaseColumnAttributeCheck typeCheck = FACTORY.createDatabaseColumnAttributeCheck(); + typeCheck.setAttributeType(DatabaseColumnAttribute.TYPE); + typeCheck.setExpectedValue(type); + columnCheck.getColumnAttributeChecks().add(typeCheck); + columnCheck.setEnabled(true); + return columnCheck; + } + private CubeCheck createCubeCheck() { + CubeCheck cubeCheck = FACTORY.createCubeCheck(); + cubeCheck.setName("Access Catalog Gran Cube Check"); + cubeCheck.setDescription("Verify Access Catalog Gran cube structure with all dimensions and measures"); + cubeCheck.setCubeName("Cube1"); + cubeCheck.setEnabled(true); + // Add cube attribute checks + CubeAttributeCheck visibleCheck = FACTORY.createCubeAttributeCheck(); + visibleCheck.setName("Cube Visibility Check"); + visibleCheck.setAttributeType(CubeAttribute.VISIBLE); + visibleCheck.setExpectedBoolean(true); + + cubeCheck.getCubeAttributeChecks().add(visibleCheck); + // Add measure checks + cubeCheck.getMeasureChecks().add(createMeasureCheck("Measure1", "sum")); + return cubeCheck; + } + + private MeasureCheck createMeasureCheck(String measureName, String expectedAggregator) { + MeasureCheck measureCheck = FACTORY.createMeasureCheck(); + measureCheck.setName(measureName + " Measure Check"); + measureCheck.setMeasureName(measureName); + measureCheck.setEnabled(true); + MeasureAttributeCheck visibleCheck = FACTORY.createMeasureAttributeCheck(); + visibleCheck.setName(measureName + " Visible Check"); + visibleCheck.setAttributeType(MeasureAttribute.VISIBLE); + visibleCheck.setExpectedBoolean(true); + measureCheck.getMeasureAttributeChecks().add(visibleCheck); + MeasureAttributeCheck aggregatorCheck = FACTORY.createMeasureAttributeCheck(); + aggregatorCheck.setName(measureName + " Aggregator Check"); + aggregatorCheck.setAttributeType(MeasureAttribute.AGGREGATOR); + aggregatorCheck.setExpectedValue(expectedAggregator); + aggregatorCheck.setMatchMode(MatchMode.EQUALS); + aggregatorCheck.setCaseSensitive(false); + measureCheck.getMeasureAttributeChecks().add(aggregatorCheck); + return measureCheck; + } + private QueryCheck createQueryCheckForRoleAll() { + QueryCheck queryCheck = FACTORY.createQueryCheck(); + queryCheck.setName("Measure Query Check"); + queryCheck.setDescription("Verify MDX query returns Measure data"); + queryCheck.setQuery("SELECT FROM [Cube1] WHERE ([Measures].[Measure1])"); + queryCheck.setQueryLanguage(QueryLanguage.MDX); + queryCheck.setExpectedColumnCount(1); + queryCheck.setEnabled(true); + queryCheck.getRoles().add("roleAll"); + return queryCheck; + } + +} diff --git a/check/instance/tutorial/access/columngrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/columngrand/package-info.java b/check/instance/tutorial/access/columngrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/columngrand/package-info.java new file mode 100644 index 0000000..e329560 --- /dev/null +++ b/check/instance/tutorial/access/columngrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/columngrand/package-info.java @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * + */ +@org.osgi.annotation.bundle.Export +@org.osgi.annotation.versioning.Version("0.0.1") +package org.eclipse.daanse.olap.check.instance.tutorial.access.columngrand; diff --git a/check/instance/tutorial/access/cubegrand/pom.xml b/check/instance/tutorial/access/cubegrand/pom.xml new file mode 100644 index 0000000..0fffacb --- /dev/null +++ b/check/instance/tutorial/access/cubegrand/pom.xml @@ -0,0 +1,31 @@ + + + + 4.0.0 + + org.eclipse.daanse + org.eclipse.daanse.olap.check.instance.tutorial.access + ${revision} + + org.eclipse.daanse.olap.check.instance.tutorial.access.cubegrand + + + + org.eclipse.daanse + org.eclipse.daanse.olap.check.model.emf + ${revision} + compile + + + + \ No newline at end of file diff --git a/check/instance/tutorial/access/cubegrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/cubegrand/CatalogCheckSupplier.java b/check/instance/tutorial/access/cubegrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/cubegrand/CatalogCheckSupplier.java new file mode 100644 index 0000000..b986728 --- /dev/null +++ b/check/instance/tutorial/access/cubegrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/cubegrand/CatalogCheckSupplier.java @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.instance.tutorial.access.cubegrand; +import org.eclipse.daanse.olap.check.model.check.CatalogCheck; +import org.eclipse.daanse.olap.check.model.check.CubeAttribute; +import org.eclipse.daanse.olap.check.model.check.CubeAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.CubeCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnAttribute; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseSchemaCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseTableCheck; +import org.eclipse.daanse.olap.check.model.check.DimensionAttribute; +import org.eclipse.daanse.olap.check.model.check.DimensionAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.DimensionCheck; +import org.eclipse.daanse.olap.check.model.check.HierarchyAttribute; +import org.eclipse.daanse.olap.check.model.check.HierarchyAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.HierarchyCheck; +import org.eclipse.daanse.olap.check.model.check.LevelCheck; +import org.eclipse.daanse.olap.check.model.check.MatchMode; +import org.eclipse.daanse.olap.check.model.check.MeasureAttribute; +import org.eclipse.daanse.olap.check.model.check.MeasureAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.MeasureCheck; +import org.eclipse.daanse.olap.check.model.check.OlapCheckFactory; +import org.eclipse.daanse.olap.check.model.check.OlapCheckModel; +import org.eclipse.daanse.olap.check.model.check.QueryCheck; +import org.eclipse.daanse.olap.check.model.check.QueryLanguage; +import org.eclipse.daanse.olap.check.model.check.RoleCheck; +import org.osgi.service.component.annotations.Component; + +@Component(service = CatalogCheckSupplier.class) +public class CatalogCheckSupplier implements org.eclipse.daanse.olap.check.model.provider.CatalogCheckSupplier { + private static final OlapCheckFactory FACTORY = OlapCheckFactory.eINSTANCE; + + @Override + public OlapCheckModel get() { + OlapCheckModel model = FACTORY.createOlapCheckModel(); + model.setName("Daanse Tutorial - Access Cube Grand Checks"); + model.setDescription("Comprehensive checks for Access Cube Grand catalog - logistics and package delivery analysis"); + // Create catalog check + CatalogCheck catalogCheck = FACTORY.createCatalogCheck(); + catalogCheck.setName("Parcel Catalog Check"); + catalogCheck.setDescription("Demonstrates access control with cube grants and roles"); + catalogCheck.setCatalogName("Daanse Tutorial - Access Cube Grant"); + catalogCheck.setEnabled(true); + // Add database schema check with detailed column checks + catalogCheck.getDatabaseSchemaChecks().add(createDatabaseSchemaCheck()); + // Add cube check + catalogCheck.getCubeChecks().add(createCubeCheck()); + // Add role check + RoleCheck role1Check = FACTORY.createRoleCheck(); + role1Check.setName("role1 Check"); + role1Check.setRoleName("role1"); + catalogCheck.getRoleChecks().add(role1Check); + + // Add query checks at catalog level + catalogCheck.getQueryChecks().addAll(java.util.List.of( + createQueryCheckForRole1() + )); + model.getCatalogChecks().add(catalogCheck); + return model; + } + + private DatabaseSchemaCheck createDatabaseSchemaCheck() { + DatabaseSchemaCheck schemaCheck = FACTORY.createDatabaseSchemaCheck(); + schemaCheck.setName("Daanse Tutorial - Access Cube Grand Database Schema Check"); + schemaCheck.setDescription("Verify database tables and columns exist for Daanse Tutorial - Access Cube Grand"); + schemaCheck.setEnabled(true); + // Check parcels fact table with columns + DatabaseTableCheck factTableCheck = FACTORY.createDatabaseTableCheck(); + factTableCheck.setTableName("Fact"); + factTableCheck.setEnabled(true); + // Add column checks for Fact table + factTableCheck.getColumnChecks().add(createColumnCheck("KEY", "VARCHAR")); + factTableCheck.getColumnChecks().add(createColumnCheck("VALUE", "INTEGER")); + schemaCheck.getTableChecks().add(factTableCheck); + return schemaCheck; + } + private DatabaseColumnCheck createColumnCheck(String columnName, String type) { + DatabaseColumnCheck columnCheck = FACTORY.createDatabaseColumnCheck(); + columnCheck.setName(columnName + " Column Check"); + columnCheck.setColumnName(columnName); + DatabaseColumnAttributeCheck typeCheck = FACTORY.createDatabaseColumnAttributeCheck(); + typeCheck.setAttributeType(DatabaseColumnAttribute.TYPE); + typeCheck.setExpectedValue(type); + columnCheck.getColumnAttributeChecks().add(typeCheck); + columnCheck.setEnabled(true); + return columnCheck; + } + private CubeCheck createCubeCheck() { + CubeCheck cubeCheck = FACTORY.createCubeCheck(); + cubeCheck.setName("Access Cube Grant Check"); + cubeCheck.setDescription("Verify Access Cube Gran cube structure with all dimensions and measures"); + cubeCheck.setCubeName("Cube1"); + cubeCheck.setEnabled(true); + // Add cube attribute checks + CubeAttributeCheck visibleCheck = FACTORY.createCubeAttributeCheck(); + visibleCheck.setName("Cube Visibility Check"); + visibleCheck.setAttributeType(CubeAttribute.VISIBLE); + visibleCheck.setExpectedBoolean(true); + + cubeCheck.getCubeAttributeChecks().add(visibleCheck); + // Add dimension checks + cubeCheck.getDimensionChecks().add(createDimensionCheck("Dimension1", null)); + // Add measure checks + cubeCheck.getMeasureChecks().add(createMeasureCheck("Measure1", "sum")); + return cubeCheck; + } + + private DimensionCheck createDimensionCheck(String dimensionName, String description) { + DimensionCheck dimCheck = FACTORY.createDimensionCheck(); + dimCheck.setName(dimensionName + " Dimension Check"); + dimCheck.setDescription(description); + dimCheck.setDimensionName(dimensionName); + dimCheck.setEnabled(true); + + DimensionAttributeCheck visibleCheck = FACTORY.createDimensionAttributeCheck(); + visibleCheck.setName(dimensionName + " Visible Check"); + visibleCheck.setAttributeType(DimensionAttribute.VISIBLE); + visibleCheck.setExpectedBoolean(true); + dimCheck.getDimensionAttributeChecks().add(visibleCheck); + + HierarchyCheck hierarchyCheck = FACTORY.createHierarchyCheck(); + hierarchyCheck.setName("Hierarchy1 Hierarchy Check"); + hierarchyCheck.setEnabled(true); + hierarchyCheck.setHierarchyName("Hierarchy1"); + + HierarchyAttributeCheck hasAllCheck = FACTORY.createHierarchyAttributeCheck(); + hasAllCheck.setName("Hierarchy1 Type HasAll Check"); + hasAllCheck.setAttributeType(HierarchyAttribute.HAS_ALL); + hasAllCheck.setExpectedBoolean(false); + hierarchyCheck.getHierarchyAttributeChecks().add(hasAllCheck); + + LevelCheck levelCheck = FACTORY.createLevelCheck(); + levelCheck.setName("Level1 Level Check"); + levelCheck.setLevelName("Level1"); + levelCheck.setDescription("Verify level Level1 exists"); + levelCheck.setEnabled(true); + + hierarchyCheck.getLevelChecks().add(levelCheck); + dimCheck.getHierarchyChecks().add(hierarchyCheck); + + return dimCheck; + } + + private MeasureCheck createMeasureCheck(String measureName, String expectedAggregator) { + MeasureCheck measureCheck = FACTORY.createMeasureCheck(); + measureCheck.setName(measureName + " Measure Check"); + measureCheck.setMeasureName(measureName); + measureCheck.setEnabled(true); + MeasureAttributeCheck visibleCheck = FACTORY.createMeasureAttributeCheck(); + visibleCheck.setName(measureName + " Visible Check"); + visibleCheck.setAttributeType(MeasureAttribute.VISIBLE); + visibleCheck.setExpectedBoolean(true); + measureCheck.getMeasureAttributeChecks().add(visibleCheck); + MeasureAttributeCheck aggregatorCheck = FACTORY.createMeasureAttributeCheck(); + aggregatorCheck.setName(measureName + " Aggregator Check"); + aggregatorCheck.setAttributeType(MeasureAttribute.AGGREGATOR); + aggregatorCheck.setExpectedValue(expectedAggregator); + aggregatorCheck.setMatchMode(MatchMode.EQUALS); + aggregatorCheck.setCaseSensitive(false); + measureCheck.getMeasureAttributeChecks().add(aggregatorCheck); + return measureCheck; + } + private QueryCheck createQueryCheckForRole1() { + QueryCheck queryCheck = FACTORY.createQueryCheck(); + queryCheck.setName("Measure Query Check"); + queryCheck.setDescription("Verify MDX query returns Measure data for role1"); + queryCheck.setQuery("SELECT FROM [Cube1] WHERE ([Measures].[Measure1])"); + queryCheck.setQueryLanguage(QueryLanguage.MDX); + queryCheck.setExpectedColumnCount(1); + queryCheck.setEnabled(true); + queryCheck.getRoles().add("role1"); + return queryCheck; + } + +} diff --git a/check/instance/tutorial/access/cubegrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/cubegrand/package-info.java b/check/instance/tutorial/access/cubegrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/cubegrand/package-info.java new file mode 100644 index 0000000..3663827 --- /dev/null +++ b/check/instance/tutorial/access/cubegrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/cubegrand/package-info.java @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * + */ +@org.osgi.annotation.bundle.Export +@org.osgi.annotation.versioning.Version("0.0.1") +package org.eclipse.daanse.olap.check.instance.tutorial.access.cubegrand; diff --git a/check/instance/tutorial/access/databasegrand/pom.xml b/check/instance/tutorial/access/databasegrand/pom.xml new file mode 100644 index 0000000..80cb3f5 --- /dev/null +++ b/check/instance/tutorial/access/databasegrand/pom.xml @@ -0,0 +1,31 @@ + + + + 4.0.0 + + org.eclipse.daanse + org.eclipse.daanse.olap.check.instance.tutorial.access + ${revision} + + org.eclipse.daanse.olap.check.instance.tutorial.access.databasegrand + + + + org.eclipse.daanse + org.eclipse.daanse.olap.check.model.emf + ${revision} + compile + + + + \ No newline at end of file diff --git a/check/instance/tutorial/access/databasegrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/databasegrand/CatalogCheckSupplier.java b/check/instance/tutorial/access/databasegrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/databasegrand/CatalogCheckSupplier.java new file mode 100644 index 0000000..2e65ab2 --- /dev/null +++ b/check/instance/tutorial/access/databasegrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/databasegrand/CatalogCheckSupplier.java @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.instance.tutorial.access.databasegrand; +import org.eclipse.daanse.olap.check.model.check.CatalogCheck; +import org.eclipse.daanse.olap.check.model.check.CubeAttribute; +import org.eclipse.daanse.olap.check.model.check.CubeAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.CubeCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnAttribute; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseSchemaCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseTableCheck; +import org.eclipse.daanse.olap.check.model.check.MatchMode; +import org.eclipse.daanse.olap.check.model.check.MeasureAttribute; +import org.eclipse.daanse.olap.check.model.check.MeasureAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.MeasureCheck; +import org.eclipse.daanse.olap.check.model.check.OlapCheckFactory; +import org.eclipse.daanse.olap.check.model.check.OlapCheckModel; +import org.eclipse.daanse.olap.check.model.check.QueryCheck; +import org.eclipse.daanse.olap.check.model.check.QueryLanguage; +import org.eclipse.daanse.olap.check.model.check.RoleCheck; +import org.osgi.service.component.annotations.Component; + +@Component(service = CatalogCheckSupplier.class) +public class CatalogCheckSupplier implements org.eclipse.daanse.olap.check.model.provider.CatalogCheckSupplier { + private static final OlapCheckFactory FACTORY = OlapCheckFactory.eINSTANCE; + + @Override + public OlapCheckModel get() { + OlapCheckModel model = FACTORY.createOlapCheckModel(); + model.setName("Daanse Tutorial - Access Database Schema Grant Checks"); + model.setDescription("Comprehensive checks for Daanse Tutorial - Access Database Schema Grant catalog - logistics and package delivery analysis"); + //ConnectionConfig connectionConfig = FACTORY.createConnectionConfig(); + //connectionConfig.setCatalogName("Daanse Tutorial - Access Catalog Gran"); + //connectionConfig.getRoles().add("role1"); + //model.setConnectionConfig(connectionConfig); + // Create catalog check + CatalogCheck catalogCheck = FACTORY.createCatalogCheck(); + catalogCheck.setName("Catalog Check"); + catalogCheck.setDescription("Demonstrates access control with database grants and roles"); + catalogCheck.setCatalogName("Daanse Tutorial - Access Database Schema Grant"); + catalogCheck.setEnabled(true); + // Add database schema check with detailed column checks + catalogCheck.getDatabaseSchemaChecks().add(createDatabaseSchemaCheck()); + // Add cube check + catalogCheck.getCubeChecks().add(createCubeCheck()); + // Add role check + RoleCheck roleAllCheck = FACTORY.createRoleCheck(); + roleAllCheck.setName("roleAll Check"); + roleAllCheck.setRoleName("roleAll"); + catalogCheck.getRoleChecks().add(roleAllCheck); + + RoleCheck roleNoneCheck = FACTORY.createRoleCheck(); + roleNoneCheck.setName("roleNone Check"); + roleNoneCheck.setRoleName("roleNone"); + catalogCheck.getRoleChecks().add(roleNoneCheck); + + // Add query checks at catalog + catalogCheck.getQueryChecks().addAll(java.util.List.of( + createQueryCheckForRoleAll(), + createQueryCheckForRoleNone() + )); + + model.getCatalogChecks().add(catalogCheck); + return model; + } + + private DatabaseSchemaCheck createDatabaseSchemaCheck() { + DatabaseSchemaCheck schemaCheck = FACTORY.createDatabaseSchemaCheck(); + schemaCheck.setName("Daanse Tutorial - Access Database Schema Grant Check"); + schemaCheck.setDescription("Verify database tables and columns exist for Daanse Tutorial - Access Database Schema Grant"); + schemaCheck.setEnabled(true); + // Check parcels fact table with columns + DatabaseTableCheck factTableCheck = FACTORY.createDatabaseTableCheck(); + factTableCheck.setTableName("Fact"); + factTableCheck.setEnabled(true); + // Add column checks for Fact table + factTableCheck.getColumnChecks().add(createColumnCheck("KEY", "VARCHAR")); + factTableCheck.getColumnChecks().add(createColumnCheck("VALUE", "INTEGER")); + schemaCheck.getTableChecks().add(factTableCheck); + return schemaCheck; + } + private DatabaseColumnCheck createColumnCheck(String columnName, String type) { + DatabaseColumnCheck columnCheck = FACTORY.createDatabaseColumnCheck(); + columnCheck.setName(columnName + " Column Check"); + columnCheck.setColumnName(columnName); + DatabaseColumnAttributeCheck typeCheck = FACTORY.createDatabaseColumnAttributeCheck(); + typeCheck.setAttributeType(DatabaseColumnAttribute.TYPE); + typeCheck.setExpectedValue(type); + columnCheck.getColumnAttributeChecks().add(typeCheck); + columnCheck.setEnabled(true); + return columnCheck; + } + private CubeCheck createCubeCheck() { + CubeCheck cubeCheck = FACTORY.createCubeCheck(); + cubeCheck.setName("Access Database Schema Grant Cube Check"); + cubeCheck.setDescription("Verify Access Database Schema Grant cube structure with all dimensions and measures"); + cubeCheck.setCubeName("Cube1"); + cubeCheck.setEnabled(true); + // Add cube attribute checks + CubeAttributeCheck visibleCheck = FACTORY.createCubeAttributeCheck(); + visibleCheck.setName("Cube Visibility Check"); + visibleCheck.setAttributeType(CubeAttribute.VISIBLE); + visibleCheck.setExpectedBoolean(true); + + cubeCheck.getCubeAttributeChecks().add(visibleCheck); + // Add measure checks + cubeCheck.getMeasureChecks().add(createMeasureCheck("Measure1", "sum")); + return cubeCheck; + } + + private MeasureCheck createMeasureCheck(String measureName, String expectedAggregator) { + MeasureCheck measureCheck = FACTORY.createMeasureCheck(); + measureCheck.setName(measureName + " Measure Check"); + measureCheck.setMeasureName(measureName); + measureCheck.setEnabled(true); + MeasureAttributeCheck visibleCheck = FACTORY.createMeasureAttributeCheck(); + visibleCheck.setName(measureName + " Visible Check"); + visibleCheck.setAttributeType(MeasureAttribute.VISIBLE); + visibleCheck.setExpectedBoolean(true); + measureCheck.getMeasureAttributeChecks().add(visibleCheck); + MeasureAttributeCheck aggregatorCheck = FACTORY.createMeasureAttributeCheck(); + aggregatorCheck.setName(measureName + " Aggregator Check"); + aggregatorCheck.setAttributeType(MeasureAttribute.AGGREGATOR); + aggregatorCheck.setExpectedValue(expectedAggregator); + aggregatorCheck.setMatchMode(MatchMode.EQUALS); + aggregatorCheck.setCaseSensitive(false); + measureCheck.getMeasureAttributeChecks().add(aggregatorCheck); + return measureCheck; + } + private QueryCheck createQueryCheckForRoleAll() { + QueryCheck queryCheck = FACTORY.createQueryCheck(); + queryCheck.setName("Measure Query Check"); + queryCheck.setDescription("Verify MDX query returns Measure data"); + queryCheck.setQuery("SELECT FROM [Cube1] WHERE ([Measures].[Measure1])"); + queryCheck.setQueryLanguage(QueryLanguage.MDX); + queryCheck.setExpectedColumnCount(1); + queryCheck.setEnabled(true); + queryCheck.getRoles().add("roleAll"); + return queryCheck; + } + + private QueryCheck createQueryCheckForRoleNone() { + QueryCheck queryCheck = FACTORY.createQueryCheck(); + queryCheck.setName("Measure Query Check"); + queryCheck.setDescription("Verify MDX query returns Measure data"); + queryCheck.setQuery("SELECT FROM [Cube1] WHERE ([Measures].[Measure1])"); + queryCheck.setQueryLanguage(QueryLanguage.MDX); + queryCheck.setExpectedColumnCount(0); + queryCheck.setEnabled(true); + queryCheck.getRoles().add("roleNone"); + return queryCheck; + } +} diff --git a/check/instance/tutorial/access/databasegrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/databasegrand/package-info.java b/check/instance/tutorial/access/databasegrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/databasegrand/package-info.java new file mode 100644 index 0000000..eba0a33 --- /dev/null +++ b/check/instance/tutorial/access/databasegrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/databasegrand/package-info.java @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * + */ +@org.osgi.annotation.bundle.Export +@org.osgi.annotation.versioning.Version("0.0.1") +package org.eclipse.daanse.olap.check.instance.tutorial.access.databasegrand; diff --git a/check/instance/tutorial/access/defaultrolegrand/pom.xml b/check/instance/tutorial/access/defaultrolegrand/pom.xml new file mode 100644 index 0000000..e459bb5 --- /dev/null +++ b/check/instance/tutorial/access/defaultrolegrand/pom.xml @@ -0,0 +1,31 @@ + + + + 4.0.0 + + org.eclipse.daanse + org.eclipse.daanse.olap.check.instance.tutorial.access + ${revision} + + org.eclipse.daanse.olap.check.instance.tutorial.access.defaultrolegrand + + + + org.eclipse.daanse + org.eclipse.daanse.olap.check.model.emf + ${revision} + compile + + + + \ No newline at end of file diff --git a/check/instance/tutorial/access/defaultrolegrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/defaultrolegrand/CatalogCheckSupplier.java b/check/instance/tutorial/access/defaultrolegrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/defaultrolegrand/CatalogCheckSupplier.java new file mode 100644 index 0000000..806fbbd --- /dev/null +++ b/check/instance/tutorial/access/defaultrolegrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/defaultrolegrand/CatalogCheckSupplier.java @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.instance.tutorial.access.defaultrolegrand; +import org.eclipse.daanse.olap.check.model.check.CatalogCheck; +import org.eclipse.daanse.olap.check.model.check.CubeAttribute; +import org.eclipse.daanse.olap.check.model.check.CubeAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.CubeCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnAttribute; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseSchemaCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseTableCheck; +import org.eclipse.daanse.olap.check.model.check.DimensionAttribute; +import org.eclipse.daanse.olap.check.model.check.DimensionAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.DimensionCheck; +import org.eclipse.daanse.olap.check.model.check.HierarchyAttribute; +import org.eclipse.daanse.olap.check.model.check.HierarchyAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.HierarchyCheck; +import org.eclipse.daanse.olap.check.model.check.LevelCheck; +import org.eclipse.daanse.olap.check.model.check.MatchMode; +import org.eclipse.daanse.olap.check.model.check.MeasureAttribute; +import org.eclipse.daanse.olap.check.model.check.MeasureAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.MeasureCheck; +import org.eclipse.daanse.olap.check.model.check.OlapCheckFactory; +import org.eclipse.daanse.olap.check.model.check.OlapCheckModel; +import org.eclipse.daanse.olap.check.model.check.QueryCheck; +import org.eclipse.daanse.olap.check.model.check.QueryLanguage; +import org.eclipse.daanse.olap.check.model.check.RoleCheck; +import org.osgi.service.component.annotations.Component; + +@Component(service = CatalogCheckSupplier.class) +public class CatalogCheckSupplier implements org.eclipse.daanse.olap.check.model.provider.CatalogCheckSupplier { + private static final OlapCheckFactory FACTORY = OlapCheckFactory.eINSTANCE; + + @Override + public OlapCheckModel get() { + OlapCheckModel model = FACTORY.createOlapCheckModel(); + model.setName("Daanse Tutorial - Access With Default Role Checks"); + model.setDescription("Comprehensive checks for Daanse Tutorial - Access With Default Role catalog - logistics and package delivery analysis"); + // Create catalog check + CatalogCheck catalogCheck = FACTORY.createCatalogCheck(); + catalogCheck.setName("Catalog Check"); + catalogCheck.setDescription("Demonstrates access control with default role"); + catalogCheck.setCatalogName("Daanse Tutorial - Access With Default Role"); + catalogCheck.setEnabled(true); + // Add database schema check with detailed column checks + catalogCheck.getDatabaseSchemaChecks().add(createDatabaseSchemaCheck()); + // Add cube check + catalogCheck.getCubeChecks().add(createCubeCheck()); + // Add role check + RoleCheck role1Check = FACTORY.createRoleCheck(); + role1Check.setName("role1 Check"); + role1Check.setRoleName("role1"); + catalogCheck.getRoleChecks().add(role1Check); + + // Add query checks at catalog level + catalogCheck.getQueryChecks().addAll(java.util.List.of( + createQueryCheckForRole1(), + createQueryCheckWithoutRole() + )); + model.getCatalogChecks().add(catalogCheck); + return model; + } + + private DatabaseSchemaCheck createDatabaseSchemaCheck() { + DatabaseSchemaCheck schemaCheck = FACTORY.createDatabaseSchemaCheck(); + schemaCheck.setName("Daanse Tutorial - Access With Default Role Database Schema Check"); + schemaCheck.setDescription("Verify database tables and columns exist for Daanse Tutorial - Access With Default Role"); + schemaCheck.setEnabled(true); + // Check parcels fact table with columns + DatabaseTableCheck factTableCheck = FACTORY.createDatabaseTableCheck(); + factTableCheck.setTableName("Fact"); + factTableCheck.setEnabled(true); + // Add column checks for Fact table + factTableCheck.getColumnChecks().add(createColumnCheck("KEY", "VARCHAR")); + factTableCheck.getColumnChecks().add(createColumnCheck("VALUE", "INTEGER")); + schemaCheck.getTableChecks().add(factTableCheck); + return schemaCheck; + } + private DatabaseColumnCheck createColumnCheck(String columnName, String type) { + DatabaseColumnCheck columnCheck = FACTORY.createDatabaseColumnCheck(); + columnCheck.setName(columnName + " Column Check"); + columnCheck.setColumnName(columnName); + DatabaseColumnAttributeCheck typeCheck = FACTORY.createDatabaseColumnAttributeCheck(); + typeCheck.setAttributeType(DatabaseColumnAttribute.TYPE); + typeCheck.setExpectedValue(type); + columnCheck.getColumnAttributeChecks().add(typeCheck); + columnCheck.setEnabled(true); + return columnCheck; + } + private CubeCheck createCubeCheck() { + CubeCheck cubeCheck = FACTORY.createCubeCheck(); + cubeCheck.setName("Daanse Tutorial - Access With Default Role Cube Check"); + cubeCheck.setDescription("Verify Daanse Tutorial - Access With Default Role cube structure with all dimensions and measures"); + cubeCheck.setCubeName("Cube1"); + cubeCheck.setEnabled(true); + // Add cube attribute checks + CubeAttributeCheck visibleCheck = FACTORY.createCubeAttributeCheck(); + visibleCheck.setName("Cube Visibility Check"); + visibleCheck.setAttributeType(CubeAttribute.VISIBLE); + visibleCheck.setExpectedBoolean(true); + + cubeCheck.getCubeAttributeChecks().add(visibleCheck); + // Add dimension checks + cubeCheck.getDimensionChecks().add(createDimension1Check()); + // Add measure checks + cubeCheck.getMeasureChecks().add(createMeasureCheck("Measure1", "sum")); + return cubeCheck; + } + + private DimensionCheck createDimension1Check() { + DimensionCheck dimCheck = FACTORY.createDimensionCheck(); + dimCheck.setName("Dimension1 Dimension Check"); + dimCheck.setDescription("Dimension1 Dimension Check"); + dimCheck.setDimensionName("Dimension1"); + dimCheck.setEnabled(true); + + DimensionAttributeCheck visibleCheck = FACTORY.createDimensionAttributeCheck(); + visibleCheck.setName("Dimension1 Visible Check"); + visibleCheck.setAttributeType(DimensionAttribute.VISIBLE); + visibleCheck.setExpectedBoolean(true); + dimCheck.getDimensionAttributeChecks().add(visibleCheck); + + HierarchyCheck hierarchy1Check = FACTORY.createHierarchyCheck(); + hierarchy1Check.setName("Hierarchy1 Hierarchy Check"); + hierarchy1Check.setHierarchyName("Hierarchy1"); + hierarchy1Check.setEnabled(true); + + HierarchyAttributeCheck hierarchy1HasAllCheck = FACTORY.createHierarchyAttributeCheck(); + hierarchy1HasAllCheck.setName("Hierarchy1 HasAll Check"); + hierarchy1HasAllCheck.setAttributeType(HierarchyAttribute.HAS_ALL); + hierarchy1HasAllCheck.setExpectedBoolean(false); + hierarchy1Check.getHierarchyAttributeChecks().add(hierarchy1HasAllCheck); + + LevelCheck level1Check = FACTORY.createLevelCheck(); + level1Check.setName("Level1 Level Check"); + level1Check.setLevelName("Level1"); + level1Check.setDescription("Verify level Level1 exists"); + level1Check.setEnabled(true); + + hierarchy1Check.getLevelChecks().add(level1Check); + + HierarchyCheck hierarchy2Check = FACTORY.createHierarchyCheck(); + hierarchy1Check.setName("Hierarchy2 Hierarchy Check"); + hierarchy1Check.setHierarchyName("Hierarchy2"); + hierarchy1Check.setEnabled(true); + + HierarchyAttributeCheck hierarchy2HasAllCheck = FACTORY.createHierarchyAttributeCheck(); + hierarchy2HasAllCheck.setName("Hierarchy2 HasAll Check"); + hierarchy2HasAllCheck.setAttributeType(HierarchyAttribute.HAS_ALL); + hierarchy2HasAllCheck.setExpectedBoolean(false); + hierarchy2Check.getHierarchyAttributeChecks().add(hierarchy1HasAllCheck); + + LevelCheck level2Check = FACTORY.createLevelCheck(); + level2Check.setName("Level2 Level Check"); + level2Check.setLevelName("Level2"); + level2Check.setDescription("Verify level Level2 exists"); + level2Check.setEnabled(true); + + hierarchy1Check.getLevelChecks().add(level2Check); + + dimCheck.getHierarchyChecks().add(hierarchy1Check); + dimCheck.getHierarchyChecks().add(hierarchy2Check); + + return dimCheck; + } + + private MeasureCheck createMeasureCheck(String measureName, String expectedAggregator) { + MeasureCheck measureCheck = FACTORY.createMeasureCheck(); + measureCheck.setName(measureName + " Measure Check"); + measureCheck.setMeasureName(measureName); + measureCheck.setEnabled(true); + MeasureAttributeCheck visibleCheck = FACTORY.createMeasureAttributeCheck(); + visibleCheck.setName(measureName + " Visible Check"); + visibleCheck.setAttributeType(MeasureAttribute.VISIBLE); + visibleCheck.setExpectedBoolean(true); + measureCheck.getMeasureAttributeChecks().add(visibleCheck); + MeasureAttributeCheck aggregatorCheck = FACTORY.createMeasureAttributeCheck(); + aggregatorCheck.setName(measureName + " Aggregator Check"); + aggregatorCheck.setAttributeType(MeasureAttribute.AGGREGATOR); + aggregatorCheck.setExpectedValue(expectedAggregator); + aggregatorCheck.setMatchMode(MatchMode.EQUALS); + aggregatorCheck.setCaseSensitive(false); + measureCheck.getMeasureAttributeChecks().add(aggregatorCheck); + return measureCheck; + } + private QueryCheck createQueryCheckForRole1() { + QueryCheck queryCheck = FACTORY.createQueryCheck(); + queryCheck.setName("Measure Query Check"); + queryCheck.setDescription("Verify MDX query returns Measure data"); + queryCheck.setQuery("SELECT FROM [Cube1] WHERE ([Measures].[Measure1])"); + queryCheck.setQueryLanguage(QueryLanguage.MDX); + queryCheck.setExpectedColumnCount(1); + queryCheck.setEnabled(true); + queryCheck.getRoles().add("role1"); + return queryCheck; + } + + private QueryCheck createQueryCheckWithoutRole() { + QueryCheck queryCheck = FACTORY.createQueryCheck(); + queryCheck.setName("Measure Query Check"); + queryCheck.setDescription("Verify MDX query returns Measure data"); + queryCheck.setQuery("SELECT FROM [Cube1] WHERE ([Measures].[Measure1])"); + queryCheck.setQueryLanguage(QueryLanguage.MDX); + queryCheck.setExpectedColumnCount(1); + queryCheck.setEnabled(true); + return queryCheck; + } + +} diff --git a/check/instance/tutorial/access/defaultrolegrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/defaultrolegrand/package-info.java b/check/instance/tutorial/access/defaultrolegrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/defaultrolegrand/package-info.java new file mode 100644 index 0000000..6b82ff2 --- /dev/null +++ b/check/instance/tutorial/access/defaultrolegrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/defaultrolegrand/package-info.java @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * + */ +@org.osgi.annotation.bundle.Export +@org.osgi.annotation.versioning.Version("0.0.1") +package org.eclipse.daanse.olap.check.instance.tutorial.access.defaultrolegrand; diff --git a/check/instance/tutorial/access/dimensiongrand/pom.xml b/check/instance/tutorial/access/dimensiongrand/pom.xml new file mode 100644 index 0000000..3575245 --- /dev/null +++ b/check/instance/tutorial/access/dimensiongrand/pom.xml @@ -0,0 +1,31 @@ + + + + 4.0.0 + + org.eclipse.daanse + org.eclipse.daanse.olap.check.instance.tutorial.access + ${revision} + + org.eclipse.daanse.olap.check.instance.tutorial.access.dimensiongrand + + + + org.eclipse.daanse + org.eclipse.daanse.olap.check.model.emf + ${revision} + compile + + + + \ No newline at end of file diff --git a/check/instance/tutorial/access/dimensiongrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/dimensiongrand/CatalogCheckSupplier.java b/check/instance/tutorial/access/dimensiongrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/dimensiongrand/CatalogCheckSupplier.java new file mode 100644 index 0000000..f1dc5f5 --- /dev/null +++ b/check/instance/tutorial/access/dimensiongrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/dimensiongrand/CatalogCheckSupplier.java @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.instance.tutorial.access.dimensiongrand; +import org.eclipse.daanse.olap.check.model.check.CatalogCheck; +import org.eclipse.daanse.olap.check.model.check.CubeAttribute; +import org.eclipse.daanse.olap.check.model.check.CubeAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.CubeCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnAttribute; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseSchemaCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseTableCheck; +import org.eclipse.daanse.olap.check.model.check.DimensionAttribute; +import org.eclipse.daanse.olap.check.model.check.DimensionAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.DimensionCheck; +import org.eclipse.daanse.olap.check.model.check.HierarchyAttribute; +import org.eclipse.daanse.olap.check.model.check.HierarchyAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.HierarchyCheck; +import org.eclipse.daanse.olap.check.model.check.LevelCheck; +import org.eclipse.daanse.olap.check.model.check.MatchMode; +import org.eclipse.daanse.olap.check.model.check.MeasureAttribute; +import org.eclipse.daanse.olap.check.model.check.MeasureAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.MeasureCheck; +import org.eclipse.daanse.olap.check.model.check.OlapCheckFactory; +import org.eclipse.daanse.olap.check.model.check.OlapCheckModel; +import org.eclipse.daanse.olap.check.model.check.QueryCheck; +import org.eclipse.daanse.olap.check.model.check.QueryLanguage; +import org.eclipse.daanse.olap.check.model.check.RoleCheck; +import org.osgi.service.component.annotations.Component; + +@Component(service = CatalogCheckSupplier.class) +public class CatalogCheckSupplier implements org.eclipse.daanse.olap.check.model.provider.CatalogCheckSupplier { + private static final OlapCheckFactory FACTORY = OlapCheckFactory.eINSTANCE; + + @Override + public OlapCheckModel get() { + OlapCheckModel model = FACTORY.createOlapCheckModel(); + model.setName("Daanse Tutorial - Access Dimension Grant Catalog Checks"); + model.setDescription("Comprehensive checks for Daanse Tutorial - Access Dimension Grant catalog - logistics and package delivery analysis"); + // Create catalog check + CatalogCheck catalogCheck = FACTORY.createCatalogCheck(); + catalogCheck.setName("Parcel Catalog Check"); + catalogCheck.setDescription("Demonstrates access control with dimension grants and roles"); + catalogCheck.setCatalogName("Daanse Tutorial - Access Dimension Grant"); + catalogCheck.setEnabled(true); + // Add database schema check with detailed column checks + catalogCheck.getDatabaseSchemaChecks().add(createDatabaseSchemaCheck()); + // Add cube check + catalogCheck.getCubeChecks().add(createCubeCheck()); + // Add role check + RoleCheck role1Check = FACTORY.createRoleCheck(); + role1Check.setName("role1 Check"); + role1Check.setRoleName("role1"); + catalogCheck.getRoleChecks().add(role1Check); + // Add query checks at catalog level + catalogCheck.getQueryChecks().addAll(java.util.List.of( + createQueryCheckForRole1() + )); + model.getCatalogChecks().add(catalogCheck); + return model; + } + + private DatabaseSchemaCheck createDatabaseSchemaCheck() { + DatabaseSchemaCheck schemaCheck = FACTORY.createDatabaseSchemaCheck(); + schemaCheck.setName("Daanse Tutorial - Access Dimension Grant Database Schema Check"); + schemaCheck.setDescription("Verify database tables and columns exist for Daanse Tutorial - Access Dimension Grant"); + schemaCheck.setEnabled(true); + // Check parcels fact table with columns + DatabaseTableCheck factTableCheck = FACTORY.createDatabaseTableCheck(); + factTableCheck.setTableName("Fact"); + factTableCheck.setEnabled(true); + // Add column checks for Fact table + factTableCheck.getColumnChecks().add(createColumnCheck("KEY", "VARCHAR")); + factTableCheck.getColumnChecks().add(createColumnCheck("VALUE", "INTEGER")); + schemaCheck.getTableChecks().add(factTableCheck); + return schemaCheck; + } + private DatabaseColumnCheck createColumnCheck(String columnName, String type) { + DatabaseColumnCheck columnCheck = FACTORY.createDatabaseColumnCheck(); + columnCheck.setName(columnName + " Column Check"); + columnCheck.setColumnName(columnName); + DatabaseColumnAttributeCheck typeCheck = FACTORY.createDatabaseColumnAttributeCheck(); + typeCheck.setAttributeType(DatabaseColumnAttribute.TYPE); + typeCheck.setExpectedValue(type); + columnCheck.getColumnAttributeChecks().add(typeCheck); + columnCheck.setEnabled(true); + return columnCheck; + } + private CubeCheck createCubeCheck() { + CubeCheck cubeCheck = FACTORY.createCubeCheck(); + cubeCheck.setName("Daanse Tutorial - Access Dimension Grant Cube Check"); + cubeCheck.setDescription("Verify Access Dimension Gran cube structure with all dimensions and measures"); + cubeCheck.setCubeName("Cube1"); + cubeCheck.setEnabled(true); + // Add cube attribute checks + CubeAttributeCheck visibleCheck = FACTORY.createCubeAttributeCheck(); + visibleCheck.setName("Cube Visibility Check"); + visibleCheck.setAttributeType(CubeAttribute.VISIBLE); + visibleCheck.setExpectedBoolean(true); + + cubeCheck.getCubeAttributeChecks().add(visibleCheck); + // Add dimension checks + cubeCheck.getDimensionChecks().add(createDimension1Check()); + cubeCheck.getDimensionChecks().add(createDimension2Check()); + // Add measure checks + cubeCheck.getMeasureChecks().add(createMeasureCheck("Measure1", "sum")); + return cubeCheck; + } + + private DimensionCheck createDimension1Check() { + DimensionCheck dimCheck = FACTORY.createDimensionCheck(); + dimCheck.setName("Dimension1 Dimension Check"); + dimCheck.setDescription("Dimension1 Dimension Check"); + dimCheck.setDimensionName("Dimension1"); + dimCheck.setEnabled(true); + + DimensionAttributeCheck visibleCheck = FACTORY.createDimensionAttributeCheck(); + visibleCheck.setName("Dimension1 Visible Check"); + visibleCheck.setAttributeType(DimensionAttribute.VISIBLE); + visibleCheck.setExpectedBoolean(true); + dimCheck.getDimensionAttributeChecks().add(visibleCheck); + + HierarchyCheck hierarchyCheck = FACTORY.createHierarchyCheck(); + hierarchyCheck.setName("Hierarchy1 Hierarchy Check"); + hierarchyCheck.setEnabled(true); + + HierarchyAttributeCheck hasAllCheck = FACTORY.createHierarchyAttributeCheck(); + hasAllCheck.setName("Hierarchy2 HasAll Check"); + hasAllCheck.setAttributeType(HierarchyAttribute.HAS_ALL); + hasAllCheck.setExpectedBoolean(false); + hierarchyCheck.getHierarchyAttributeChecks().add(hasAllCheck); + + LevelCheck levelCheck = FACTORY.createLevelCheck(); + levelCheck.setName("Level1 Level Check"); + levelCheck.setLevelName("Level1"); + levelCheck.setDescription("Verify level Level1 exists"); + levelCheck.setEnabled(true); + + hierarchyCheck.getLevelChecks().add(levelCheck); + dimCheck.getHierarchyChecks().add(hierarchyCheck); + + return dimCheck; + } + + private DimensionCheck createDimension2Check() { + DimensionCheck dimCheck = FACTORY.createDimensionCheck(); + dimCheck.setName("Dimension2 Dimension Check"); + dimCheck.setDescription("Dimension2 Dimension Check"); + dimCheck.setDimensionName("Dimension2"); + dimCheck.setEnabled(true); + + DimensionAttributeCheck visibleCheck = FACTORY.createDimensionAttributeCheck(); + visibleCheck.setName("Dimension2 Visible Check"); + visibleCheck.setAttributeType(DimensionAttribute.VISIBLE); + visibleCheck.setExpectedBoolean(true); + dimCheck.getDimensionAttributeChecks().add(visibleCheck); + + HierarchyCheck hierarchyCheck = FACTORY.createHierarchyCheck(); + hierarchyCheck.setName("Hierarchy2 Hierarchy Check"); + hierarchyCheck.setEnabled(false); + + HierarchyAttributeCheck hasAllCheck = FACTORY.createHierarchyAttributeCheck(); + hasAllCheck.setName("Hierarchy2 HasAll Check"); + hasAllCheck.setAttributeType(HierarchyAttribute.HAS_ALL); + hasAllCheck.setExpectedBoolean(true); + hierarchyCheck.getHierarchyAttributeChecks().add(hasAllCheck); + + LevelCheck levelCheck = FACTORY.createLevelCheck(); + levelCheck.setName("Level2 Level Check"); + levelCheck.setLevelName("Level2"); + levelCheck.setDescription("Verify level Level2 exists"); + levelCheck.setEnabled(true); + + hierarchyCheck.getLevelChecks().add(levelCheck); + dimCheck.getHierarchyChecks().add(hierarchyCheck); + + return dimCheck; + } + + private MeasureCheck createMeasureCheck(String measureName, String expectedAggregator) { + MeasureCheck measureCheck = FACTORY.createMeasureCheck(); + measureCheck.setName(measureName + " Measure Check"); + measureCheck.setMeasureName(measureName); + measureCheck.setEnabled(true); + MeasureAttributeCheck visibleCheck = FACTORY.createMeasureAttributeCheck(); + visibleCheck.setName(measureName + " Visible Check"); + visibleCheck.setAttributeType(MeasureAttribute.VISIBLE); + visibleCheck.setExpectedBoolean(true); + measureCheck.getMeasureAttributeChecks().add(visibleCheck); + MeasureAttributeCheck aggregatorCheck = FACTORY.createMeasureAttributeCheck(); + aggregatorCheck.setName(measureName + " Aggregator Check"); + aggregatorCheck.setAttributeType(MeasureAttribute.AGGREGATOR); + aggregatorCheck.setExpectedValue(expectedAggregator); + aggregatorCheck.setMatchMode(MatchMode.EQUALS); + aggregatorCheck.setCaseSensitive(false); + measureCheck.getMeasureAttributeChecks().add(aggregatorCheck); + return measureCheck; + } + private QueryCheck createQueryCheckForRole1() { + QueryCheck queryCheck = FACTORY.createQueryCheck(); + queryCheck.setName("Measure Query Check"); + queryCheck.setDescription("Verify MDX query Dimension1 Hierarchy1"); + queryCheck.setQuery("SELECT NON EMPTY Hierarchize(AddCalculatedMembers({DrilldownLevel({[Dimension1].[Hierarchy1].[All Hierarchy1s]})})) DIMENSION PROPERTIES PARENT_UNIQUE_NAME ON COLUMNS FROM [Cube1] WHERE ([Measures].[Measure1])"); + queryCheck.setQueryLanguage(QueryLanguage.MDX); + queryCheck.setExpectedColumnCount(1); + queryCheck.setEnabled(true); + queryCheck.getRoles().add("role1"); + return queryCheck; + } + +} diff --git a/check/instance/tutorial/access/dimensiongrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/dimensiongrand/package-info.java b/check/instance/tutorial/access/dimensiongrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/dimensiongrand/package-info.java new file mode 100644 index 0000000..f76743d --- /dev/null +++ b/check/instance/tutorial/access/dimensiongrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/dimensiongrand/package-info.java @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * + */ +@org.osgi.annotation.bundle.Export +@org.osgi.annotation.versioning.Version("0.0.1") +package org.eclipse.daanse.olap.check.instance.tutorial.access.dimensiongrand; diff --git a/check/instance/tutorial/access/hierarchygrand/pom.xml b/check/instance/tutorial/access/hierarchygrand/pom.xml new file mode 100644 index 0000000..ec3888e --- /dev/null +++ b/check/instance/tutorial/access/hierarchygrand/pom.xml @@ -0,0 +1,31 @@ + + + + 4.0.0 + + org.eclipse.daanse + org.eclipse.daanse.olap.check.instance.tutorial.access + ${revision} + + org.eclipse.daanse.olap.check.instance.tutorial.access.hierarchygrand + + + + org.eclipse.daanse + org.eclipse.daanse.olap.check.model.emf + ${revision} + compile + + + + \ No newline at end of file diff --git a/check/instance/tutorial/access/hierarchygrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/hierarchygrand/CatalogCheckSupplier.java b/check/instance/tutorial/access/hierarchygrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/hierarchygrand/CatalogCheckSupplier.java new file mode 100644 index 0000000..40093fb --- /dev/null +++ b/check/instance/tutorial/access/hierarchygrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/hierarchygrand/CatalogCheckSupplier.java @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.instance.tutorial.access.hierarchygrand; +import org.eclipse.daanse.olap.check.model.check.CatalogCheck; +import org.eclipse.daanse.olap.check.model.check.CubeAttribute; +import org.eclipse.daanse.olap.check.model.check.CubeAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.CubeCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnAttribute; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseSchemaCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseTableCheck; +import org.eclipse.daanse.olap.check.model.check.DimensionAttribute; +import org.eclipse.daanse.olap.check.model.check.DimensionAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.DimensionCheck; +import org.eclipse.daanse.olap.check.model.check.HierarchyAttribute; +import org.eclipse.daanse.olap.check.model.check.HierarchyAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.HierarchyCheck; +import org.eclipse.daanse.olap.check.model.check.LevelCheck; +import org.eclipse.daanse.olap.check.model.check.MatchMode; +import org.eclipse.daanse.olap.check.model.check.MeasureAttribute; +import org.eclipse.daanse.olap.check.model.check.MeasureAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.MeasureCheck; +import org.eclipse.daanse.olap.check.model.check.OlapCheckFactory; +import org.eclipse.daanse.olap.check.model.check.OlapCheckModel; +import org.eclipse.daanse.olap.check.model.check.QueryCheck; +import org.eclipse.daanse.olap.check.model.check.QueryLanguage; +import org.eclipse.daanse.olap.check.model.check.RoleCheck; +import org.osgi.service.component.annotations.Component; + +@Component(service = CatalogCheckSupplier.class) +public class CatalogCheckSupplier implements org.eclipse.daanse.olap.check.model.provider.CatalogCheckSupplier { + private static final OlapCheckFactory FACTORY = OlapCheckFactory.eINSTANCE; + + @Override + public OlapCheckModel get() { + OlapCheckModel model = FACTORY.createOlapCheckModel(); + model.setName("Daanse Tutorial - Access Hierarchy Grant Catalog Checks"); + model.setDescription("Comprehensive checks for Daanse Tutorial - Access Hierarchy Grant catalog - logistics and package delivery analysis"); + //ConnectionConfig connectionConfig = FACTORY.createConnectionConfig(); + //connectionConfig.setCatalogName("Daanse Tutorial - Access Catalog Gran"); + //connectionConfig.getRoles().add("role1"); + //model.setConnectionConfig(connectionConfig); + // Create catalog check + CatalogCheck catalogCheck = FACTORY.createCatalogCheck(); + catalogCheck.setName("Daanse Tutorial - Access Hierarchy Grant Catalog Check"); + catalogCheck.setDescription("Demonstrates access control with hierarchy grants and roles"); + catalogCheck.setCatalogName("Daanse Tutorial - Access Hierarchy Grant"); + catalogCheck.setEnabled(true); + // Add database schema check with detailed column checks + catalogCheck.getDatabaseSchemaChecks().add(createDatabaseSchemaCheck()); + // Add cube check + catalogCheck.getCubeChecks().add(createCubeCheck()); + // Add role check + RoleCheck role1Check = FACTORY.createRoleCheck(); + role1Check.setName("role1 Check"); + role1Check.setRoleName("role1"); + catalogCheck.getRoleChecks().add(role1Check); + // Add query checks at catalog level + catalogCheck.getQueryChecks().addAll(java.util.List.of( + createQueryCheckForRole1() + )); + model.getCatalogChecks().add(catalogCheck); + return model; + } + + private DatabaseSchemaCheck createDatabaseSchemaCheck() { + DatabaseSchemaCheck schemaCheck = FACTORY.createDatabaseSchemaCheck(); + schemaCheck.setName("Daanse Tutorial - Access Hierarchy Grant Database Schema Check"); + schemaCheck.setDescription("Verify database tables and columns exist for Daanse Tutorial - Access Hierarchy Grant"); + schemaCheck.setEnabled(true); + // Check parcels fact table with columns + DatabaseTableCheck factTableCheck = FACTORY.createDatabaseTableCheck(); + factTableCheck.setTableName("Fact"); + factTableCheck.setEnabled(true); + // Add column checks for Fact table + factTableCheck.getColumnChecks().add(createColumnCheck("KEY", "VARCHAR")); + factTableCheck.getColumnChecks().add(createColumnCheck("VALUE", "INTEGER")); + schemaCheck.getTableChecks().add(factTableCheck); + return schemaCheck; + } + private DatabaseColumnCheck createColumnCheck(String columnName, String type) { + DatabaseColumnCheck columnCheck = FACTORY.createDatabaseColumnCheck(); + columnCheck.setName(columnName + " Column Check"); + columnCheck.setColumnName(columnName); + DatabaseColumnAttributeCheck typeCheck = FACTORY.createDatabaseColumnAttributeCheck(); + typeCheck.setAttributeType(DatabaseColumnAttribute.TYPE); + typeCheck.setExpectedValue(type); + columnCheck.getColumnAttributeChecks().add(typeCheck); + columnCheck.setEnabled(true); + return columnCheck; + } + private CubeCheck createCubeCheck() { + CubeCheck cubeCheck = FACTORY.createCubeCheck(); + cubeCheck.setName("Daanse Tutorial - Access Hierarchy Grant Cube Check"); + cubeCheck.setDescription("Verify Daanse Tutorial - Access Hierarchy Grant cube structure with all dimensions and measures"); + cubeCheck.setCubeName("Cube1"); + cubeCheck.setEnabled(true); + // Add cube attribute checks + CubeAttributeCheck visibleCheck = FACTORY.createCubeAttributeCheck(); + visibleCheck.setName("Cube Visibility Check"); + visibleCheck.setAttributeType(CubeAttribute.VISIBLE); + visibleCheck.setExpectedBoolean(true); + + cubeCheck.getCubeAttributeChecks().add(visibleCheck); + // Add dimension checks + cubeCheck.getDimensionChecks().add(createDimension1Check()); + // Add measure checks + cubeCheck.getMeasureChecks().add(createMeasureCheck("Measure1", "sum")); + return cubeCheck; + } + + private DimensionCheck createDimension1Check() { + DimensionCheck dimCheck = FACTORY.createDimensionCheck(); + dimCheck.setName("Dimension1 Dimension Check"); + dimCheck.setDescription("Dimension1 Dimension Check"); + dimCheck.setDimensionName("Dimension1"); + dimCheck.setEnabled(true); + + DimensionAttributeCheck visibleCheck = FACTORY.createDimensionAttributeCheck(); + visibleCheck.setName("Dimension1 Visible Check"); + visibleCheck.setAttributeType(DimensionAttribute.VISIBLE); + visibleCheck.setExpectedBoolean(true); + dimCheck.getDimensionAttributeChecks().add(visibleCheck); + + HierarchyCheck hierarchy1Check = FACTORY.createHierarchyCheck(); + hierarchy1Check.setName("Hierarchy1 Hierarchy Check"); + hierarchy1Check.setHierarchyName("Hierarchy1"); + hierarchy1Check.setEnabled(true); + + HierarchyAttributeCheck hierarchy1HasAllCheck = FACTORY.createHierarchyAttributeCheck(); + hierarchy1HasAllCheck.setName("Hierarchy1 HasAll Check"); + hierarchy1HasAllCheck.setAttributeType(HierarchyAttribute.HAS_ALL); + hierarchy1HasAllCheck.setExpectedBoolean(false); + hierarchy1Check.getHierarchyAttributeChecks().add(hierarchy1HasAllCheck); + + LevelCheck level1Check = FACTORY.createLevelCheck(); + level1Check.setName("Level1 Level Check"); + level1Check.setLevelName("Level1"); + level1Check.setDescription("Verify level Level1 exists"); + level1Check.setEnabled(true); + + hierarchy1Check.getLevelChecks().add(level1Check); + + HierarchyCheck hierarchy2Check = FACTORY.createHierarchyCheck(); + hierarchy1Check.setName("Hierarchy2 Hierarchy Check"); + hierarchy1Check.setHierarchyName("Hierarchy2"); + hierarchy1Check.setEnabled(true); + + HierarchyAttributeCheck hierarchy2HasAllCheck = FACTORY.createHierarchyAttributeCheck(); + hierarchy2HasAllCheck.setName("Hierarchy2 HasAll Check"); + hierarchy2HasAllCheck.setAttributeType(HierarchyAttribute.HAS_ALL); + hierarchy2HasAllCheck.setExpectedBoolean(false); + hierarchy2Check.getHierarchyAttributeChecks().add(hierarchy1HasAllCheck); + + LevelCheck level2Check = FACTORY.createLevelCheck(); + level2Check.setName("Level2 Level Check"); + level2Check.setLevelName("Level2"); + level2Check.setDescription("Verify level Level2 exists"); + level2Check.setEnabled(true); + + hierarchy1Check.getLevelChecks().add(level2Check); + + dimCheck.getHierarchyChecks().add(hierarchy1Check); + dimCheck.getHierarchyChecks().add(hierarchy2Check); + + return dimCheck; + } + + private MeasureCheck createMeasureCheck(String measureName, String expectedAggregator) { + MeasureCheck measureCheck = FACTORY.createMeasureCheck(); + measureCheck.setName(measureName + " Measure Check"); + measureCheck.setMeasureName(measureName); + measureCheck.setEnabled(true); + MeasureAttributeCheck visibleCheck = FACTORY.createMeasureAttributeCheck(); + visibleCheck.setName(measureName + " Visible Check"); + visibleCheck.setAttributeType(MeasureAttribute.VISIBLE); + visibleCheck.setExpectedBoolean(true); + measureCheck.getMeasureAttributeChecks().add(visibleCheck); + MeasureAttributeCheck aggregatorCheck = FACTORY.createMeasureAttributeCheck(); + aggregatorCheck.setName(measureName + " Aggregator Check"); + aggregatorCheck.setAttributeType(MeasureAttribute.AGGREGATOR); + aggregatorCheck.setExpectedValue(expectedAggregator); + aggregatorCheck.setMatchMode(MatchMode.EQUALS); + aggregatorCheck.setCaseSensitive(false); + measureCheck.getMeasureAttributeChecks().add(aggregatorCheck); + return measureCheck; + } + private QueryCheck createQueryCheckForRole1() { + QueryCheck queryCheck = FACTORY.createQueryCheck(); + queryCheck.setName("Measure Query Check"); + queryCheck.setDescription("Verify MDX query returns Measure data"); + queryCheck.setQuery("SELECT NON EMPTY Hierarchize(AddCalculatedMembers({DrilldownLevel({[Dimension1].[Hierarchy1].[All Hierarchy1s]})})) DIMENSION PROPERTIES PARENT_UNIQUE_NAME ON COLUMNS FROM [Cube1] WHERE ([Measures].[Measure1])"); + queryCheck.setQueryLanguage(QueryLanguage.MDX); + queryCheck.setExpectedColumnCount(1); + queryCheck.setEnabled(true); + queryCheck.getRoles().add("role1"); + return queryCheck; + } + +} diff --git a/check/instance/tutorial/access/hierarchygrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/hierarchygrand/package-info.java b/check/instance/tutorial/access/hierarchygrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/hierarchygrand/package-info.java new file mode 100644 index 0000000..cbd0152 --- /dev/null +++ b/check/instance/tutorial/access/hierarchygrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/hierarchygrand/package-info.java @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * + */ +@org.osgi.annotation.bundle.Export +@org.osgi.annotation.versioning.Version("0.0.1") +package org.eclipse.daanse.olap.check.instance.tutorial.access.hierarchygrand; diff --git a/check/instance/tutorial/access/membergrand/pom.xml b/check/instance/tutorial/access/membergrand/pom.xml new file mode 100644 index 0000000..071986e --- /dev/null +++ b/check/instance/tutorial/access/membergrand/pom.xml @@ -0,0 +1,31 @@ + + + + 4.0.0 + + org.eclipse.daanse + org.eclipse.daanse.olap.check.instance.tutorial.access + ${revision} + + org.eclipse.daanse.olap.check.instance.tutorial.access.membergrand + + + + org.eclipse.daanse + org.eclipse.daanse.olap.check.model.emf + ${revision} + compile + + + + \ No newline at end of file diff --git a/check/instance/tutorial/access/membergrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/membergrand/CatalogCheckSupplier.java b/check/instance/tutorial/access/membergrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/membergrand/CatalogCheckSupplier.java new file mode 100644 index 0000000..04b6f6c --- /dev/null +++ b/check/instance/tutorial/access/membergrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/membergrand/CatalogCheckSupplier.java @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.instance.tutorial.access.membergrand; +import org.eclipse.daanse.olap.check.model.check.CatalogCheck; +import org.eclipse.daanse.olap.check.model.check.CubeAttribute; +import org.eclipse.daanse.olap.check.model.check.CubeAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.CubeCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnAttribute; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseSchemaCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseTableCheck; +import org.eclipse.daanse.olap.check.model.check.DimensionAttribute; +import org.eclipse.daanse.olap.check.model.check.DimensionAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.DimensionCheck; +import org.eclipse.daanse.olap.check.model.check.HierarchyAttribute; +import org.eclipse.daanse.olap.check.model.check.HierarchyAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.HierarchyCheck; +import org.eclipse.daanse.olap.check.model.check.LevelCheck; +import org.eclipse.daanse.olap.check.model.check.MatchMode; +import org.eclipse.daanse.olap.check.model.check.MeasureAttribute; +import org.eclipse.daanse.olap.check.model.check.MeasureAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.MeasureCheck; +import org.eclipse.daanse.olap.check.model.check.OlapCheckFactory; +import org.eclipse.daanse.olap.check.model.check.OlapCheckModel; +import org.eclipse.daanse.olap.check.model.check.QueryCheck; +import org.eclipse.daanse.olap.check.model.check.QueryLanguage; +import org.eclipse.daanse.olap.check.model.check.RoleAccessCheck; +import org.eclipse.daanse.olap.check.model.check.RoleCheck; +import org.osgi.service.component.annotations.Component; + +@Component(service = CatalogCheckSupplier.class) +public class CatalogCheckSupplier implements org.eclipse.daanse.olap.check.model.provider.CatalogCheckSupplier { + private static final OlapCheckFactory FACTORY = OlapCheckFactory.eINSTANCE; + + @Override + public OlapCheckModel get() { + OlapCheckModel model = FACTORY.createOlapCheckModel(); + model.setName("Daanse Tutorial - Access Member Grant Catalog Checks"); + model.setDescription("Comprehensive checks for Daanse Tutorial - Access Member Grant catalog - logistics and package delivery analysis"); + //ConnectionConfig connectionConfig = FACTORY.createConnectionConfig(); + //connectionConfig.setCatalogName("Daanse Tutorial - Access Catalog Gran"); + //connectionConfig.getRoles().add("role1"); + //model.setConnectionConfig(connectionConfig); + // Create catalog check + CatalogCheck catalogCheck = FACTORY.createCatalogCheck(); + catalogCheck.setName("Daanse Tutorial - Access Member Grant Catalog Check"); + catalogCheck.setDescription("Demonstrates access control with member grants and roles"); + catalogCheck.setCatalogName("Daanse Tutorial - Access Member Grant"); + catalogCheck.setEnabled(true); + // Add database schema check with detailed column checks + catalogCheck.getDatabaseSchemaChecks().add(createDatabaseSchemaCheck()); + // Add cube check + catalogCheck.getCubeChecks().add(createCubeCheck()); + // Add role check + RoleCheck role1Check = FACTORY.createRoleCheck(); + role1Check.setName("role1 Check"); + role1Check.setRoleName("role1"); + catalogCheck.getRoleChecks().add(role1Check); + // Add query checks at catalog level + catalogCheck.getQueryChecks().addAll(java.util.List.of( + createQueryCheckForRole1() + )); + RoleAccessCheck roleAccessCheck = FACTORY.createRoleAccessCheck(); + model.getCatalogChecks().add(catalogCheck); + return model; + } + + private DatabaseSchemaCheck createDatabaseSchemaCheck() { + DatabaseSchemaCheck schemaCheck = FACTORY.createDatabaseSchemaCheck(); + schemaCheck.setName("Daanse Tutorial - Access Member Grant Database Schema Check"); + schemaCheck.setDescription("Verify database tables and columns exist for Daanse Tutorial - Access Member Grant"); + schemaCheck.setEnabled(true); + // Check parcels fact table with columns + DatabaseTableCheck factTableCheck = FACTORY.createDatabaseTableCheck(); + factTableCheck.setTableName("Fact"); + factTableCheck.setEnabled(true); + // Add column checks for Fact table + factTableCheck.getColumnChecks().add(createColumnCheck("KEY", "VARCHAR")); + factTableCheck.getColumnChecks().add(createColumnCheck("VALUE", "INTEGER")); + schemaCheck.getTableChecks().add(factTableCheck); + return schemaCheck; + } + private DatabaseColumnCheck createColumnCheck(String columnName, String type) { + DatabaseColumnCheck columnCheck = FACTORY.createDatabaseColumnCheck(); + columnCheck.setName(columnName + " Column Check"); + columnCheck.setColumnName(columnName); + DatabaseColumnAttributeCheck typeCheck = FACTORY.createDatabaseColumnAttributeCheck(); + typeCheck.setAttributeType(DatabaseColumnAttribute.TYPE); + typeCheck.setExpectedValue(type); + columnCheck.getColumnAttributeChecks().add(typeCheck); + columnCheck.setEnabled(true); + return columnCheck; + } + private CubeCheck createCubeCheck() { + CubeCheck cubeCheck = FACTORY.createCubeCheck(); + cubeCheck.setName("Daanse Tutorial - Access Member Grant Cube Check"); + cubeCheck.setDescription("Verify Daanse Tutorial - Access Member Grant cube structure with all dimensions and measures"); + cubeCheck.setCubeName("Cube1"); + cubeCheck.setEnabled(true); + // Add cube attribute checks + CubeAttributeCheck visibleCheck = FACTORY.createCubeAttributeCheck(); + visibleCheck.setName("Cube Visibility Check"); + visibleCheck.setAttributeType(CubeAttribute.VISIBLE); + visibleCheck.setExpectedBoolean(true); + + cubeCheck.getCubeAttributeChecks().add(visibleCheck); + // Add dimension checks + cubeCheck.getDimensionChecks().add(createDimensionCheck("Dimension1", null)); + // Add measure checks + cubeCheck.getMeasureChecks().add(createMeasureCheck("Measure1", "sum")); + return cubeCheck; + } + private DimensionCheck createDimensionCheck(String dimensionName, String description) { + DimensionCheck dimCheck = FACTORY.createDimensionCheck(); + dimCheck.setName(dimensionName + " Dimension Check"); + dimCheck.setDescription(description); + dimCheck.setDimensionName(dimensionName); + dimCheck.setEnabled(true); + + DimensionAttributeCheck visibleCheck = FACTORY.createDimensionAttributeCheck(); + visibleCheck.setName(dimensionName + " Visible Check"); + visibleCheck.setAttributeType(DimensionAttribute.VISIBLE); + visibleCheck.setExpectedBoolean(true); + dimCheck.getDimensionAttributeChecks().add(visibleCheck); + + HierarchyCheck hierarchyCheck = FACTORY.createHierarchyCheck(); + hierarchyCheck.setName("Hierarchy1 Hierarchy Check"); + hierarchyCheck.setEnabled(true); + + HierarchyAttributeCheck hasAllCheck = FACTORY.createHierarchyAttributeCheck(); + hasAllCheck.setName("Hierarchy HasAll Check"); + hasAllCheck.setAttributeType(HierarchyAttribute.HAS_ALL); + hasAllCheck.setExpectedBoolean(true); + hierarchyCheck.getHierarchyAttributeChecks().add(hasAllCheck); + + LevelCheck levelCheck = FACTORY.createLevelCheck(); + levelCheck.setName("Level1 Level Check"); + levelCheck.setLevelName("Level1"); + levelCheck.setDescription("Verify level Level1 exists"); + levelCheck.setEnabled(true); + + hierarchyCheck.getLevelChecks().add(levelCheck); + dimCheck.getHierarchyChecks().add(hierarchyCheck); + + return dimCheck; + } + + private MeasureCheck createMeasureCheck(String measureName, String expectedAggregator) { + MeasureCheck measureCheck = FACTORY.createMeasureCheck(); + measureCheck.setName(measureName + " Measure Check"); + measureCheck.setMeasureName(measureName); + measureCheck.setEnabled(true); + MeasureAttributeCheck visibleCheck = FACTORY.createMeasureAttributeCheck(); + visibleCheck.setName(measureName + " Visible Check"); + visibleCheck.setAttributeType(MeasureAttribute.VISIBLE); + visibleCheck.setExpectedBoolean(true); + measureCheck.getMeasureAttributeChecks().add(visibleCheck); + MeasureAttributeCheck aggregatorCheck = FACTORY.createMeasureAttributeCheck(); + aggregatorCheck.setName(measureName + " Aggregator Check"); + aggregatorCheck.setAttributeType(MeasureAttribute.AGGREGATOR); + aggregatorCheck.setExpectedValue(expectedAggregator); + aggregatorCheck.setMatchMode(MatchMode.EQUALS); + aggregatorCheck.setCaseSensitive(false); + measureCheck.getMeasureAttributeChecks().add(aggregatorCheck); + return measureCheck; + } + private QueryCheck createQueryCheckForRole1() { + QueryCheck queryCheck = FACTORY.createQueryCheck(); + queryCheck.setName("Measure Query Check"); + queryCheck.setDescription("Verify MDX query returns Measure data"); + queryCheck.setQuery("SELECT NON EMPTY Hierarchize(AddCalculatedMembers({DrilldownLevel({[Dimension1].[Hierarchy1].[All Hierarchy1s]})})) DIMENSION PROPERTIES PARENT_UNIQUE_NAME ON COLUMNS FROM [Cube1] WHERE ([Measures].[Measure1])"); + queryCheck.setQueryLanguage(QueryLanguage.MDX); + queryCheck.setExpectedColumnCount(1); + queryCheck.setEnabled(true); + queryCheck.getRoles().add("role1"); + return queryCheck; + } + +} diff --git a/check/instance/tutorial/access/membergrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/membergrand/package-info.java b/check/instance/tutorial/access/membergrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/membergrand/package-info.java new file mode 100644 index 0000000..b645c33 --- /dev/null +++ b/check/instance/tutorial/access/membergrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/membergrand/package-info.java @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * + */ +@org.osgi.annotation.bundle.Export +@org.osgi.annotation.versioning.Version("0.0.1") +package org.eclipse.daanse.olap.check.instance.tutorial.access.membergrand; diff --git a/check/instance/tutorial/access/pom.xml b/check/instance/tutorial/access/pom.xml new file mode 100644 index 0000000..9cefebf --- /dev/null +++ b/check/instance/tutorial/access/pom.xml @@ -0,0 +1,36 @@ + + + + 4.0.0 + + org.eclipse.daanse + org.eclipse.daanse.olap.check.instance.tutorial + ${revision} + + pom + + org.eclipse.daanse.olap.check.instance.tutorial.access + + + cataloggrand + columngrand + cubegrand + databasegrand + defaultrolegrand + dimensiongrand + hierarchygrand + membergrand + + diff --git a/check/instance/tutorial/access/tablegrand/pom.xml b/check/instance/tutorial/access/tablegrand/pom.xml new file mode 100644 index 0000000..a0c306f --- /dev/null +++ b/check/instance/tutorial/access/tablegrand/pom.xml @@ -0,0 +1,31 @@ + + + + 4.0.0 + + org.eclipse.daanse + org.eclipse.daanse.olap.check.instance.tutorial.access + ${revision} + + org.eclipse.daanse.olap.check.instance.tutorial.access.tablegrand + + + + org.eclipse.daanse + org.eclipse.daanse.olap.check.model.emf + ${revision} + compile + + + + \ No newline at end of file diff --git a/check/instance/tutorial/access/tablegrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/tablegrand/CatalogCheckSupplier.java b/check/instance/tutorial/access/tablegrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/tablegrand/CatalogCheckSupplier.java new file mode 100644 index 0000000..bda25dd --- /dev/null +++ b/check/instance/tutorial/access/tablegrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/tablegrand/CatalogCheckSupplier.java @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.instance.tutorial.access.tablegrand; +import org.eclipse.daanse.olap.check.model.check.CatalogCheck; +import org.eclipse.daanse.olap.check.model.check.CubeAttribute; +import org.eclipse.daanse.olap.check.model.check.CubeAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.CubeCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnAttribute; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseSchemaCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseTableCheck; +import org.eclipse.daanse.olap.check.model.check.MatchMode; +import org.eclipse.daanse.olap.check.model.check.MeasureAttribute; +import org.eclipse.daanse.olap.check.model.check.MeasureAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.MeasureCheck; +import org.eclipse.daanse.olap.check.model.check.OlapCheckFactory; +import org.eclipse.daanse.olap.check.model.check.OlapCheckModel; +import org.eclipse.daanse.olap.check.model.check.QueryCheck; +import org.eclipse.daanse.olap.check.model.check.QueryLanguage; +import org.eclipse.daanse.olap.check.model.check.RoleCheck; +import org.osgi.service.component.annotations.Component; + +@Component(service = CatalogCheckSupplier.class) +public class CatalogCheckSupplier implements org.eclipse.daanse.olap.check.model.provider.CatalogCheckSupplier { + private static final OlapCheckFactory FACTORY = OlapCheckFactory.eINSTANCE; + + @Override + public OlapCheckModel get() { + OlapCheckModel model = FACTORY.createOlapCheckModel(); + model.setName("Daanse Tutorial - Access Table Grant Catalog Checks"); + model.setDescription("Comprehensive checks for Daanse Tutorial - Access Table Grant catalog - logistics and package delivery analysis"); + //ConnectionConfig connectionConfig = FACTORY.createConnectionConfig(); + //connectionConfig.setCatalogName("Daanse Tutorial - Access Catalog Gran"); + //connectionConfig.getRoles().add("role1"); + //model.setConnectionConfig(connectionConfig); + // Create catalog check + CatalogCheck catalogCheck = FACTORY.createCatalogCheck(); + catalogCheck.setName("Daanse Tutorial - Access Table Grant Catalog Check"); + catalogCheck.setDescription("Demonstrates access control with table grants and roles"); + catalogCheck.setCatalogName("Daanse Tutorial - Access Table Grant"); + catalogCheck.setEnabled(true); + // Add database schema check with detailed column checks + catalogCheck.getDatabaseSchemaChecks().add(createDatabaseSchemaCheck()); + // Add cube check + catalogCheck.getCubeChecks().add(createCubeCheck()); + // Add role check + RoleCheck roleAllCheck = FACTORY.createRoleCheck(); + roleAllCheck.setName("roleAll Check"); + roleAllCheck.setRoleName("roleAll"); + catalogCheck.getRoleChecks().add(roleAllCheck); + RoleCheck roleNoneCheck = FACTORY.createRoleCheck(); + roleNoneCheck.setName("roleAll Check"); + roleNoneCheck.setRoleName("roleAll"); + catalogCheck.getRoleChecks().add(roleNoneCheck); + + // Add query checks at catalog level + catalogCheck.getQueryChecks().addAll(java.util.List.of( + createQueryCheckForRoleAll() + )); + model.getCatalogChecks().add(catalogCheck); + return model; + } + + private DatabaseSchemaCheck createDatabaseSchemaCheck() { + DatabaseSchemaCheck schemaCheck = FACTORY.createDatabaseSchemaCheck(); + schemaCheck.setName("Daanse Tutorial - Access Table Grant Database Schema Check"); + schemaCheck.setDescription("Verify database tables and columns exist for Daanse Tutorial - Access Table Grant"); + schemaCheck.setEnabled(true); + // Check parcels fact table with columns + DatabaseTableCheck factTableCheck = FACTORY.createDatabaseTableCheck(); + factTableCheck.setTableName("Fact"); + factTableCheck.setEnabled(true); + // Add column checks for Fact table + factTableCheck.getColumnChecks().add(createColumnCheck("KEY", "VARCHAR")); + factTableCheck.getColumnChecks().add(createColumnCheck("VALUE", "INTEGER")); + schemaCheck.getTableChecks().add(factTableCheck); + return schemaCheck; + } + private DatabaseColumnCheck createColumnCheck(String columnName, String type) { + DatabaseColumnCheck columnCheck = FACTORY.createDatabaseColumnCheck(); + columnCheck.setName(columnName + " Column Check"); + columnCheck.setColumnName(columnName); + DatabaseColumnAttributeCheck typeCheck = FACTORY.createDatabaseColumnAttributeCheck(); + typeCheck.setAttributeType(DatabaseColumnAttribute.TYPE); + typeCheck.setExpectedValue(type); + columnCheck.getColumnAttributeChecks().add(typeCheck); + columnCheck.setEnabled(true); + return columnCheck; + } + private CubeCheck createCubeCheck() { + CubeCheck cubeCheck = FACTORY.createCubeCheck(); + cubeCheck.setName("Daanse Tutorial - Access Table Grant Cube Check"); + cubeCheck.setDescription("Verify Daanse Tutorial - Access Table Grant cube structure with all dimensions and measures"); + cubeCheck.setCubeName("Cube1"); + cubeCheck.setEnabled(true); + // Add cube attribute checks + CubeAttributeCheck visibleCheck = FACTORY.createCubeAttributeCheck(); + visibleCheck.setName("Cube Visibility Check"); + visibleCheck.setAttributeType(CubeAttribute.VISIBLE); + visibleCheck.setExpectedBoolean(true); + cubeCheck.getCubeAttributeChecks().add(visibleCheck); + // Add measure checks + cubeCheck.getMeasureChecks().add(createMeasureCheck("Measure1", "sum")); + return cubeCheck; + } + + private MeasureCheck createMeasureCheck(String measureName, String expectedAggregator) { + MeasureCheck measureCheck = FACTORY.createMeasureCheck(); + measureCheck.setName(measureName + " Measure Check"); + measureCheck.setMeasureName(measureName); + measureCheck.setEnabled(true); + MeasureAttributeCheck visibleCheck = FACTORY.createMeasureAttributeCheck(); + visibleCheck.setName(measureName + " Visible Check"); + visibleCheck.setAttributeType(MeasureAttribute.VISIBLE); + visibleCheck.setExpectedBoolean(true); + measureCheck.getMeasureAttributeChecks().add(visibleCheck); + MeasureAttributeCheck aggregatorCheck = FACTORY.createMeasureAttributeCheck(); + aggregatorCheck.setName(measureName + " Aggregator Check"); + aggregatorCheck.setAttributeType(MeasureAttribute.AGGREGATOR); + aggregatorCheck.setExpectedValue(expectedAggregator); + aggregatorCheck.setMatchMode(MatchMode.EQUALS); + aggregatorCheck.setCaseSensitive(false); + measureCheck.getMeasureAttributeChecks().add(aggregatorCheck); + return measureCheck; + } + private QueryCheck createQueryCheckForRoleAll() { + QueryCheck queryCheck = FACTORY.createQueryCheck(); + queryCheck.setName("Measure Query Check"); + queryCheck.setDescription("Verify MDX query returns Measure data"); + queryCheck.setQuery("SELECT FROM [Cube1] WHERE ([Measures].[Measure1])"); + queryCheck.setQueryLanguage(QueryLanguage.MDX); + queryCheck.setExpectedColumnCount(1); + queryCheck.setEnabled(true); + queryCheck.getRoles().add("roleAll"); + return queryCheck; + } + +} diff --git a/check/instance/tutorial/access/tablegrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/tablegrand/package-info.java b/check/instance/tutorial/access/tablegrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/tablegrand/package-info.java new file mode 100644 index 0000000..3d3263a --- /dev/null +++ b/check/instance/tutorial/access/tablegrand/src/main/java/org/eclipse/daanse/olap/check/instance/tutorial/access/tablegrand/package-info.java @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * + */ +@org.osgi.annotation.bundle.Export +@org.osgi.annotation.versioning.Version("0.0.1") +package org.eclipse.daanse.olap.check.instance.tutorial.access.tablegrand; diff --git a/check/instance/tutorial/pom.xml b/check/instance/tutorial/pom.xml new file mode 100644 index 0000000..38a9d29 --- /dev/null +++ b/check/instance/tutorial/pom.xml @@ -0,0 +1,38 @@ + + + + 4.0.0 + + org.eclipse.daanse + org.eclipse.daanse.olap.check.instance + ${revision} + + org.eclipse.daanse.olap.check.instance.tutorial + pom + + + access + + + + + org.eclipse.daanse + org.eclipse.daanse.olap.check.model.emf + ${revision} + compile + + + + diff --git a/check/model/emf/bnd.bnd b/check/model/emf/bnd.bnd new file mode 100644 index 0000000..c4cca45 --- /dev/null +++ b/check/model/emf/bnd.bnd @@ -0,0 +1,2 @@ +Bundle-Name: Eclipse Daanse OLAP Check Model EMF +Bundle-Description: EMF Ecore model for declarative OLAP check definitions and results diff --git a/check/model/emf/pom.xml b/check/model/emf/pom.xml new file mode 100644 index 0000000..fcaa948 --- /dev/null +++ b/check/model/emf/pom.xml @@ -0,0 +1,137 @@ + + + + 4.0.0 + + org.eclipse.daanse + org.eclipse.daanse.olap.check.model + ${revision} + + org.eclipse.daanse.olap.check.model.emf + Eclipse Daanse OLAP Check Model EMF + EMF Ecore model for declarative OLAP check definitions and results. Provides model-driven check definitions that can be persisted as XMI or JSON and executed by the check runtime. + + + 7.1.0 + 6.2.0 + 2.30.0 + 2.36.0 + 2.37.0 + + + + + org.geckoprojects.emf.utils + org.gecko.emf.json + 1.5.1 + compile + + + org.geckoprojects.emf + org.gecko.emf.osgi.api + ${gecko.emf.version} + compile + + + org.geckoprojects.emf + org.gecko.emf.osgi.component + ${gecko.emf.version} + compile + + + org.eclipse.emf + org.eclipse.emf.common + ${emf.common.version} + compile + + + org.eclipse.emf + org.eclipse.emf.ecore + ${emf.ecore.version} + compile + + + org.eclipse.emf + org.eclipse.emf.ecore.xmi + ${emf.ecore.xmi.version} + compile + + + + + + + biz.aQute.bnd + bnd-generate-maven-plugin + ${bnd.version} + + + + org.geckoprojects.emf + org.gecko.emf.osgi.codegen + ${gecko.emf.version} + + + + + + src/main/resources/model/org.eclipse.daanse.olap.check.genmodel + geckoEMF + target/generated-sources/emf + false + + + src/main/resources/model/org.eclipse.daanse.olap.check.genmodel + + + + + + + generate-sources + + generate + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 3.6.0 + + + generate-sources + + add-source + + + + target/generated-sources/emf + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + true + + + + + diff --git a/check/model/emf/src/main/java/org/eclipse/daanse/olap/check/model/provider/CatalogCheckSupplier.java b/check/model/emf/src/main/java/org/eclipse/daanse/olap/check/model/provider/CatalogCheckSupplier.java new file mode 100644 index 0000000..2eea13e --- /dev/null +++ b/check/model/emf/src/main/java/org/eclipse/daanse/olap/check/model/provider/CatalogCheckSupplier.java @@ -0,0 +1,9 @@ +package org.eclipse.daanse.olap.check.model.provider; + +import java.util.function.Supplier; + +import org.eclipse.daanse.olap.check.model.check.OlapCheckModel; + +public interface CatalogCheckSupplier extends Supplier { + +} \ No newline at end of file diff --git a/check/model/emf/src/main/java/org/eclipse/daanse/olap/check/model/provider/package-info.java b/check/model/emf/src/main/java/org/eclipse/daanse/olap/check/model/provider/package-info.java new file mode 100644 index 0000000..1c9fd09 --- /dev/null +++ b/check/model/emf/src/main/java/org/eclipse/daanse/olap/check/model/provider/package-info.java @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * + */ +@org.osgi.annotation.bundle.Export +@org.osgi.annotation.versioning.Version("0.0.1") +package org.eclipse.daanse.olap.check.model.provider; + diff --git a/check/model/emf/src/main/resources/model/org.eclipse.daanse.olap.check.ecore b/check/model/emf/src/main/resources/model/org.eclipse.daanse.olap.check.ecore new file mode 100644 index 0000000..cc6b009 --- /dev/null +++ b/check/model/emf/src/main/resources/model/org.eclipse.daanse.olap.check.ecore @@ -0,0 +1,799 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/check/model/emf/src/main/resources/model/org.eclipse.daanse.olap.check.genmodel b/check/model/emf/src/main/resources/model/org.eclipse.daanse.olap.check.genmodel new file mode 100644 index 0000000..e3439cd --- /dev/null +++ b/check/model/emf/src/main/resources/model/org.eclipse.daanse.olap.check.genmodel @@ -0,0 +1,696 @@ + + + + org.eclipse.daanse.olap.check.ecore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/check/model/pom.xml b/check/model/pom.xml new file mode 100644 index 0000000..7879aa4 --- /dev/null +++ b/check/model/pom.xml @@ -0,0 +1,31 @@ + + + + 4.0.0 + + org.eclipse.daanse + org.eclipse.daanse.olap.check + ${revision} + + org.eclipse.daanse.olap.check.model + pom + Eclipse Daanse OLAP Check Model + EMF model definitions for OLAP check framework. + + + emf + + + diff --git a/check/pom.xml b/check/pom.xml new file mode 100644 index 0000000..b55908c --- /dev/null +++ b/check/pom.xml @@ -0,0 +1,33 @@ + + + + 4.0.0 + + org.eclipse.daanse + org.eclipse.daanse.olap + ${revision} + + org.eclipse.daanse.olap.check + pom + Eclipse Daanse OLAP Check + OLAP Check framework for health checks, verification, warmup and system validation using declarative XMI-based check definitions. + + + model + runtime + instance + + + diff --git a/check/runtime/bnd.bnd b/check/runtime/bnd.bnd new file mode 100644 index 0000000..f56a14d --- /dev/null +++ b/check/runtime/bnd.bnd @@ -0,0 +1,2 @@ +Bundle-Name: Eclipse Daanse OLAP Check Runtime +Bundle-Description: Runtime executor for OLAP check models diff --git a/check/runtime/pom.xml b/check/runtime/pom.xml new file mode 100644 index 0000000..a465d9e --- /dev/null +++ b/check/runtime/pom.xml @@ -0,0 +1,71 @@ + + + + 4.0.0 + + org.eclipse.daanse + org.eclipse.daanse.olap.check + ${revision} + + org.eclipse.daanse.olap.check.runtime + Eclipse Daanse OLAP Check Runtime + Runtime executor for OLAP check models. Loads check definitions from XMI files, executes them against OLAP connections, and returns EMF result objects. + + + 2.30.0 + 2.36.0 + 2.37.0 + + + + + + org.eclipse.daanse + org.eclipse.daanse.olap.check.model.emf + ${project.version} + + + + + org.eclipse.daanse + org.eclipse.daanse.olap.api + ${project.version} + + + + + org.eclipse.emf + org.eclipse.emf.common + ${emf.common.version} + + + org.eclipse.emf + org.eclipse.emf.ecore + ${emf.ecore.version} + + + org.eclipse.emf + org.eclipse.emf.ecore.xmi + ${emf.ecore.xmi.version} + + + + + org.osgi + org.osgi.service.component.annotations + provided + + + diff --git a/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/api/CheckExecutor.java b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/api/CheckExecutor.java new file mode 100644 index 0000000..4355266 --- /dev/null +++ b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/api/CheckExecutor.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.runtime.api; + +import org.eclipse.daanse.olap.api.connection.Connection; +import org.eclipse.daanse.olap.check.model.check.CheckExecutionResult; +import org.eclipse.daanse.olap.check.model.check.OlapCheckModel; +import org.eclipse.emf.common.util.URI; + +/** + * Executor for OLAP check models. + *

+ * Loads check definitions from XMI files or EMF model objects, + * executes them against OLAP connections, and returns EMF result objects. + *

+ *

+ * Use cases: + *

    + *
  • System health/readiness checks
  • + *
  • Cache warmup
  • + *
  • Verification and testing
  • + *
  • Role-based access validation
  • + *
+ *

+ */ +public interface CheckExecutor { + + /** + * Execute checks defined in the model against the given connection. + * + * @param model the check model containing check definitions + * @param connection the OLAP connection to check against + * @return the execution result containing all check results + */ + CheckExecutionResult execute(OlapCheckModel model, Connection connection); + + /** + * Load a check model from URI and execute against the given connection. + * + * @param modelUri URI to the XMI file containing check definitions + * @param connection the OLAP connection to check against + * @return the execution result containing all check results + */ + CheckExecutionResult execute(URI modelUri, Connection connection); +} diff --git a/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/api/CheckModelLoader.java b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/api/CheckModelLoader.java new file mode 100644 index 0000000..b173088 --- /dev/null +++ b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/api/CheckModelLoader.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.runtime.api; + +import java.io.IOException; + +import org.eclipse.daanse.olap.check.model.check.OlapCheckModel; +import org.eclipse.emf.common.util.URI; + +/** + * Loader for OLAP check models from XMI or JSON files. + */ +public interface CheckModelLoader { + + /** + * Load a check model from an XMI file. + * + * @param uri the URI to the XMI file + * @return the loaded check model + * @throws IOException if the file cannot be read or parsed + */ + OlapCheckModel loadFromXMI(URI uri) throws IOException; + + /** + * Load a check model from a JSON file. + * + * @param uri the URI to the JSON file + * @return the loaded check model + * @throws IOException if the file cannot be read or parsed + */ + OlapCheckModel loadFromJSON(URI uri) throws IOException; +} diff --git a/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/CheckExecutorImpl.java b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/CheckExecutorImpl.java new file mode 100644 index 0000000..acc420a --- /dev/null +++ b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/CheckExecutorImpl.java @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.runtime.impl; + +import java.io.IOException; +import java.util.Date; +import java.util.List; + +import org.eclipse.daanse.olap.api.CatalogReader; +import org.eclipse.daanse.olap.api.connection.Connection; +import org.eclipse.daanse.olap.api.element.Cube; +import org.eclipse.daanse.olap.api.element.Dimension; +import org.eclipse.daanse.olap.api.element.Hierarchy; +import org.eclipse.daanse.olap.api.element.Level; +import org.eclipse.daanse.olap.api.element.Member; +import org.eclipse.daanse.olap.check.model.check.CatalogCheck; +import org.eclipse.daanse.olap.check.model.check.CatalogCheckResult; +import org.eclipse.daanse.olap.check.model.check.CheckExecutionResult; +import org.eclipse.daanse.olap.check.model.check.CheckFailure; +import org.eclipse.daanse.olap.check.model.check.CheckResult; +import org.eclipse.daanse.olap.check.model.check.CheckStatus; +import org.eclipse.daanse.olap.check.model.check.CubeCheck; +import org.eclipse.daanse.olap.check.model.check.CubeCheckResult; +import org.eclipse.daanse.olap.check.model.check.DimensionCheck; +import org.eclipse.daanse.olap.check.model.check.DimensionCheckResult; +import org.eclipse.daanse.olap.check.model.check.HierarchyCheck; +import org.eclipse.daanse.olap.check.model.check.HierarchyCheckResult; +import org.eclipse.daanse.olap.check.model.check.LevelCheck; +import org.eclipse.daanse.olap.check.model.check.LevelCheckResult; +import org.eclipse.daanse.olap.check.model.check.MemberCheck; +import org.eclipse.daanse.olap.check.model.check.MemberCheckResult; +import org.eclipse.daanse.olap.check.model.check.OlapCheck; +import org.eclipse.daanse.olap.check.model.check.OlapCheckFactory; +import org.eclipse.daanse.olap.check.model.check.OlapCheckModel; +import org.eclipse.daanse.olap.check.runtime.api.CheckExecutor; +import org.eclipse.daanse.olap.check.runtime.api.CheckModelLoader; +import org.eclipse.daanse.olap.check.runtime.impl.executors.CatalogCheckExecutor; +import org.eclipse.emf.common.util.URI; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; + +/** + * Implementation of CheckExecutor that executes OLAP check models. + */ +@Component(service = CheckExecutor.class) +public class CheckExecutorImpl implements CheckExecutor { + + private final OlapCheckFactory factory = OlapCheckFactory.eINSTANCE; + + @Reference + private CheckModelLoader modelLoader; + + @Override + public CheckExecutionResult execute(OlapCheckModel model, Connection connection) { + CheckExecutionResult result = factory.createCheckExecutionResult(); + result.setName(model.getName()); + result.setDescription(model.getDescription()); + result.setStartTime(new Date()); + result.setSourceModel(model); + + CatalogReader catalogReader = connection.getCatalogReader(); + int successCount = 0; + int failureCount = 0; + int skippedCount = 0; + + // Execute all catalog checks + for (CatalogCheck catalogCheck : model.getCatalogChecks()) { + if (!catalogCheck.isEnabled()) { + skippedCount++; + continue; + } + + CatalogCheckExecutor executor = new CatalogCheckExecutor( + catalogCheck, catalogReader, connection, factory + ); + CheckResult checkResult = executor.execute(); + result.getCheckResults().add(checkResult); + + // Count results + if (checkResult.getStatus() == CheckStatus.SUCCESS) { + successCount += countSuccesses(checkResult); + } else if (checkResult.getStatus() == CheckStatus.FAILURE) { + failureCount += countFailures(checkResult); + } else { + skippedCount++; + } + } + + result.setEndTime(new Date()); + result.setTotalExecutionTimeMs(result.getEndTime().getTime() - result.getStartTime().getTime()); + result.setSuccessCount(successCount); + result.setFailureCount(failureCount); + result.setSkippedCount(skippedCount); + result.setSuccess(failureCount == 0); + + return result; + } + + @Override + public CheckExecutionResult execute(URI modelUri, Connection connection) { + try { + OlapCheckModel model = modelLoader.loadFromXMI(modelUri); + return execute(model, connection); + } catch (IOException e) { + // Return a failure result + CheckExecutionResult result = factory.createCheckExecutionResult(); + result.setName("LoadFailure"); + result.setStartTime(new Date()); + result.setEndTime(new Date()); + result.setSuccess(false); + result.setFailureCount(1); + + CheckFailure failure = factory.createCheckFailure(); + failure.setCheckName("ModelLoad"); + failure.setStatus(CheckStatus.FAILURE); + failure.setMessage("Failed to load model from: " + modelUri); + failure.setException(e.getMessage()); + result.getCheckResults().add(failure); + + return result; + } + } + + private int countSuccesses(CheckResult result) { + int count = result.getStatus() == CheckStatus.SUCCESS ? 1 : 0; + + if (result instanceof CatalogCheckResult catalogResult) { + for (CubeCheckResult cubeResult : catalogResult.getCubeResults()) { + count += countSuccesses(cubeResult); + } + } else if (result instanceof CubeCheckResult cubeResult) { + for (DimensionCheckResult dimResult : cubeResult.getDimensionResults()) { + count += countSuccesses(dimResult); + } + } else if (result instanceof DimensionCheckResult dimResult) { + for (HierarchyCheckResult hierResult : dimResult.getHierarchyResults()) { + count += countSuccesses(hierResult); + } + } else if (result instanceof HierarchyCheckResult hierResult) { + for (LevelCheckResult levelResult : hierResult.getLevelResults()) { + count += countSuccesses(levelResult); + } + } else if (result instanceof LevelCheckResult levelResult) { + for (MemberCheckResult memberResult : levelResult.getMemberResults()) { + count += countSuccesses(memberResult); + } + } + + return count; + } + + private int countFailures(CheckResult result) { + int count = result.getStatus() == CheckStatus.FAILURE ? 1 : 0; + + if (result instanceof CatalogCheckResult catalogResult) { + for (CubeCheckResult cubeResult : catalogResult.getCubeResults()) { + count += countFailures(cubeResult); + } + } else if (result instanceof CubeCheckResult cubeResult) { + for (DimensionCheckResult dimResult : cubeResult.getDimensionResults()) { + count += countFailures(dimResult); + } + } else if (result instanceof DimensionCheckResult dimResult) { + for (HierarchyCheckResult hierResult : dimResult.getHierarchyResults()) { + count += countFailures(hierResult); + } + } else if (result instanceof HierarchyCheckResult hierResult) { + for (LevelCheckResult levelResult : hierResult.getLevelResults()) { + count += countFailures(levelResult); + } + } else if (result instanceof LevelCheckResult levelResult) { + for (MemberCheckResult memberResult : levelResult.getMemberResults()) { + count += countFailures(memberResult); + } + } + + return count; + } +} diff --git a/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/CheckModelLoaderImpl.java b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/CheckModelLoaderImpl.java new file mode 100644 index 0000000..883dcab --- /dev/null +++ b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/CheckModelLoaderImpl.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.runtime.impl; + +import java.io.IOException; + +import org.eclipse.daanse.olap.check.model.check.OlapCheckModel; +import org.eclipse.daanse.olap.check.model.check.OlapCheckPackage; +import org.eclipse.daanse.olap.check.runtime.api.CheckModelLoader; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; +import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl; +import org.osgi.service.component.annotations.Component; + +/** + * Implementation of CheckModelLoader that loads OLAP check models from XMI files. + */ +@Component(service = CheckModelLoader.class) +public class CheckModelLoaderImpl implements CheckModelLoader { + + private final ResourceSet resourceSet; + + public CheckModelLoaderImpl() { + this.resourceSet = new ResourceSetImpl(); + initialize(); + } + + private void initialize() { + // Register the package + OlapCheckPackage.eINSTANCE.eClass(); + + // Register XMI resource factory for .xmi and .olapcheck extensions + resourceSet.getResourceFactoryRegistry() + .getExtensionToFactoryMap() + .put("xmi", new XMIResourceFactoryImpl()); + + resourceSet.getResourceFactoryRegistry() + .getExtensionToFactoryMap() + .put("olapcheck", new XMIResourceFactoryImpl()); + + // Register the package in the resource set + resourceSet.getPackageRegistry() + .put(OlapCheckPackage.eNS_URI, OlapCheckPackage.eINSTANCE); + } + + @Override + public OlapCheckModel loadFromXMI(URI uri) throws IOException { + Resource resource = resourceSet.getResource(uri, true); + + if (resource.getContents().isEmpty()) { + throw new IOException("No content found in resource: " + uri); + } + + Object root = resource.getContents().get(0); + if (!(root instanceof OlapCheckModel)) { + throw new IOException( + "Root element is not an OlapCheckModel: " + root.getClass().getName() + ); + } + + return (OlapCheckModel) root; + } + + @Override + public OlapCheckModel loadFromJSON(URI uri) throws IOException { + // TODO: Implement JSON loading with Gecko EMF JSON support + throw new UnsupportedOperationException("JSON loading not yet implemented"); + } +} diff --git a/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/AttributeCheckHelper.java b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/AttributeCheckHelper.java new file mode 100644 index 0000000..11e3815 --- /dev/null +++ b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/AttributeCheckHelper.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.runtime.impl.executors; + +import org.eclipse.daanse.olap.check.model.check.MatchMode; + +/** + * Helper class for comparing attribute values with various match modes. + */ +public class AttributeCheckHelper { + + private AttributeCheckHelper() { + // Utility class + } + + public static boolean compareValues(String expected, String actual, MatchMode matchMode, boolean caseSensitive) { + if (expected == null && actual == null) { + return true; + } + if (expected == null || actual == null) { + return false; + } + + return switch (matchMode) { + case EQUALS -> caseSensitive ? expected.equals(actual) : expected.equalsIgnoreCase(actual); + case CONTAINS -> caseSensitive ? actual.contains(expected) : actual.toLowerCase().contains(expected.toLowerCase()); + case STARTS_WITH -> caseSensitive ? actual.startsWith(expected) : actual.toLowerCase().startsWith(expected.toLowerCase()); + case ENDS_WITH -> caseSensitive ? actual.endsWith(expected) : actual.toLowerCase().endsWith(expected.toLowerCase()); + case REGEX -> actual.matches(expected); + case NOT_EQUALS -> caseSensitive ? !expected.equals(actual) : !expected.equalsIgnoreCase(actual); + case NOT_CONTAINS -> caseSensitive ? !actual.contains(expected) : !actual.toLowerCase().contains(expected.toLowerCase()); + }; + } + + public static boolean compareBooleans(Boolean expected, Boolean actual) { + if (expected == null) { + return true; // No expectation set + } + return expected.equals(actual); + } + + public static boolean compareInts(Integer expected, Integer actual) { + if (expected == null) { + return true; // No expectation set + } + return expected.equals(actual); + } +} diff --git a/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/CatalogCheckExecutor.java b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/CatalogCheckExecutor.java new file mode 100644 index 0000000..845e398 --- /dev/null +++ b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/CatalogCheckExecutor.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.runtime.impl.executors; + +import java.util.Date; +import java.util.List; +import java.util.Optional; + +import org.eclipse.daanse.olap.api.CatalogReader; +import org.eclipse.daanse.olap.api.connection.Connection; +import org.eclipse.daanse.olap.api.element.DatabaseSchema; +import org.eclipse.daanse.olap.api.element.Cube; +import org.eclipse.daanse.olap.check.model.check.CatalogCheck; +import org.eclipse.daanse.olap.check.model.check.CatalogCheckResult; +import org.eclipse.daanse.olap.check.model.check.CheckResult; +import org.eclipse.daanse.olap.check.model.check.CheckStatus; +import org.eclipse.daanse.olap.check.model.check.CubeCheck; +import org.eclipse.daanse.olap.check.model.check.CubeCheckResult; +import org.eclipse.daanse.olap.check.model.check.DatabaseSchemaCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseSchemaCheckResult; +import org.eclipse.daanse.olap.check.model.check.OlapCheckFactory; +import org.eclipse.daanse.olap.check.model.check.QueryCheck; +import org.eclipse.daanse.olap.check.model.check.QueryCheckResult; + +/** + * Executor for CatalogCheck that verifies catalog structure. + */ +public class CatalogCheckExecutor { + + private final CatalogCheck check; + private final CatalogReader catalogReader; + private final Connection connection; + private final OlapCheckFactory factory; + + public CatalogCheckExecutor(CatalogCheck check, CatalogReader catalogReader, + Connection connection, OlapCheckFactory factory) { + this.check = check; + this.catalogReader = catalogReader; + this.connection = connection; + this.factory = factory; + } + + public CheckResult execute() { + long startTime = System.currentTimeMillis(); + Date start = new Date(); + + CatalogCheckResult result = factory.createCatalogCheckResult(); + result.setCheckName(check.getName()); + result.setCheckDescription(check.getDescription()); + result.setCatalogName(check.getCatalogName()); + result.setStartTime(start); + result.setSourceCheck(check); + + try { + // Get all cubes from catalog + List cubes = catalogReader.getCubes(); + + // Mark catalog check as success (we have access) + result.setStatus(CheckStatus.SUCCESS); + + // Execute cube checks + for (CubeCheck cubeCheck : check.getCubeChecks()) { + if (!cubeCheck.isEnabled()) { + continue; + } + + CubeCheckExecutor cubeExecutor = new CubeCheckExecutor( + cubeCheck, cubes, catalogReader, connection, factory + ); + CubeCheckResult cubeResult = cubeExecutor.execute(); + result.getCubeResults().add(cubeResult); + + // If any child fails, mark parent as failed + if (cubeResult.getStatus() == CheckStatus.FAILURE) { + result.setStatus(CheckStatus.FAILURE); + } + } + + // Execute database schema checks + List schemas = catalogReader.getDatabaseSchemas(); + for (DatabaseSchemaCheck schemaCheck : check.getDatabaseSchemaChecks()) { + if (!schemaCheck.isEnabled()) { + continue; + } + + DatabaseSchemaCheckExecutor schemaExecutor = new DatabaseSchemaCheckExecutor( + schemaCheck, schemas, factory + ); + DatabaseSchemaCheckResult schemaResult = schemaExecutor.execute(); + result.getDatabaseSchemaResults().add(schemaResult); + + if (schemaResult.getStatus() == CheckStatus.FAILURE) { + result.setStatus(CheckStatus.FAILURE); + } + } + + // Execute query checks (at catalog/connection level) + for (QueryCheck queryCheck : check.getQueryChecks()) { + if (!queryCheck.isEnabled()) { + continue; + } + + QueryCheckExecutor queryExecutor = new QueryCheckExecutor( + queryCheck, connection, factory + ); + QueryCheckResult queryResult = queryExecutor.execute(); + result.getQueryResults().add(queryResult); + + if (queryResult.getStatus() == CheckStatus.FAILURE) { + result.setStatus(CheckStatus.FAILURE); + } + } + + // Execute attribute checks + // TODO: Add attribute check execution + + } catch (Exception e) { + result.setStatus(CheckStatus.FAILURE); + // Create a failure message + } + + result.setEndTime(new Date()); + result.setExecutionTimeMs(System.currentTimeMillis() - startTime); + + return result; + } +} diff --git a/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/CubeCheckExecutor.java b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/CubeCheckExecutor.java new file mode 100644 index 0000000..8fcd9ab --- /dev/null +++ b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/CubeCheckExecutor.java @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.runtime.impl.executors; + +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Optional; + +import org.eclipse.daanse.olap.api.CatalogReader; +import org.eclipse.daanse.olap.api.connection.Connection; +import org.eclipse.daanse.olap.api.element.Cube; +import org.eclipse.daanse.olap.api.element.Dimension; +import org.eclipse.daanse.olap.api.element.Member; +import org.eclipse.daanse.olap.check.model.check.AttributeCheckResult; +import org.eclipse.daanse.olap.check.model.check.CheckStatus; +import org.eclipse.daanse.olap.check.model.check.CubeAttribute; +import org.eclipse.daanse.olap.check.model.check.CubeAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.CubeCheck; +import org.eclipse.daanse.olap.check.model.check.CubeCheckResult; +import org.eclipse.daanse.olap.check.model.check.DimensionCheck; +import org.eclipse.daanse.olap.check.model.check.DimensionCheckResult; +import org.eclipse.daanse.olap.check.model.check.DrillThroughActionCheck; +import org.eclipse.daanse.olap.check.model.check.DrillThroughActionCheckResult; +import org.eclipse.daanse.olap.check.model.check.KPICheck; +import org.eclipse.daanse.olap.check.model.check.KPICheckResult; +import org.eclipse.daanse.olap.check.model.check.MeasureCheck; +import org.eclipse.daanse.olap.check.model.check.MeasureCheckResult; +import org.eclipse.daanse.olap.check.model.check.NamedSetCheck; +import org.eclipse.daanse.olap.check.model.check.NamedSetCheckResult; +import org.eclipse.daanse.olap.check.model.check.OlapCheckFactory; + +/** + * Executor for CubeCheck that verifies cube existence and structure. + */ +public class CubeCheckExecutor { + + private final CubeCheck check; + private final List cubes; + private final CatalogReader catalogReader; + private final Connection connection; + private final OlapCheckFactory factory; + + public CubeCheckExecutor(CubeCheck check, List cubes, CatalogReader catalogReader, + Connection connection, OlapCheckFactory factory) { + this.check = check; + this.cubes = cubes; + this.catalogReader = catalogReader; + this.connection = connection; + this.factory = factory; + } + + public CubeCheckResult execute() { + long startTime = System.currentTimeMillis(); + Date start = new Date(); + + CubeCheckResult result = factory.createCubeCheckResult(); + result.setCheckName(check.getName()); + result.setCheckDescription(check.getDescription()); + result.setCubeName(check.getCubeName()); + result.setStartTime(start); + result.setSourceCheck(check); + + try { + // Find the cube + Optional foundCube = findCube(); + + if (foundCube.isEmpty()) { + result.setStatus(CheckStatus.FAILURE); + result.setEndTime(new Date()); + result.setExecutionTimeMs(System.currentTimeMillis() - startTime); + return result; + } + + Cube cube = foundCube.get(); + result.setCubeUniqueName(cube.getUniqueName()); + result.setStatus(CheckStatus.SUCCESS); + + // Execute attribute checks + for (CubeAttributeCheck attrCheck : check.getCubeAttributeChecks()) { + AttributeCheckResult attrResult = executeAttributeCheck(attrCheck, cube); + result.getAttributeResults().add(attrResult); + if (attrResult.getStatus() == CheckStatus.FAILURE) { + result.setStatus(CheckStatus.FAILURE); + } + } + + // Execute dimension checks + List dimensions = catalogReader.getCubeDimensions(cube); + for (DimensionCheck dimensionCheck : check.getDimensionChecks()) { + if (!dimensionCheck.isEnabled()) { + continue; + } + + DimensionCheckExecutor dimExecutor = new DimensionCheckExecutor( + dimensionCheck, dimensions, cube, catalogReader, connection, factory + ); + DimensionCheckResult dimResult = dimExecutor.execute(); + result.getDimensionResults().add(dimResult); + + if (dimResult.getStatus() == CheckStatus.FAILURE) { + result.setStatus(CheckStatus.FAILURE); + } + } + + // Execute measure checks + List measures = cube.getMeasures(); + for (MeasureCheck measureCheck : check.getMeasureChecks()) { + if (!measureCheck.isEnabled()) { + continue; + } + + MeasureCheckExecutor measureExecutor = new MeasureCheckExecutor( + measureCheck, measures, cube, catalogReader, connection, factory + ); + MeasureCheckResult measureResult = measureExecutor.execute(); + result.getMeasureResults().add(measureResult); + + if (measureResult.getStatus() == CheckStatus.FAILURE) { + result.setStatus(CheckStatus.FAILURE); + } + } + + // Execute KPI checks + for (KPICheck kpiCheck : check.getKpiChecks()) { + if (!kpiCheck.isEnabled()) { + continue; + } + + KPICheckExecutor kpiExecutor = new KPICheckExecutor( + kpiCheck, cube.getKPIs(), factory + ); + KPICheckResult kpiResult = kpiExecutor.execute(); + result.getKpiResults().add(kpiResult); + + if (kpiResult.getStatus() == CheckStatus.FAILURE) { + result.setStatus(CheckStatus.FAILURE); + } + } + + // Execute NamedSet checks + for (NamedSetCheck namedSetCheck : check.getNamedSetChecks()) { + if (!namedSetCheck.isEnabled()) { + continue; + } + + NamedSetCheckExecutor namedSetExecutor = new NamedSetCheckExecutor( + namedSetCheck, Arrays.asList(cube.getNamedSets()), factory + ); + NamedSetCheckResult namedSetResult = namedSetExecutor.execute(); + result.getNamedSetResults().add(namedSetResult); + + if (namedSetResult.getStatus() == CheckStatus.FAILURE) { + result.setStatus(CheckStatus.FAILURE); + } + } + + // Execute DrillThroughAction checks + for (DrillThroughActionCheck dtaCheck : check.getDrillThroughActionChecks()) { + if (!dtaCheck.isEnabled()) { + continue; + } + + DrillThroughActionCheckExecutor dtaExecutor = new DrillThroughActionCheckExecutor( + dtaCheck, cube.getDrillThroughActions(), factory + ); + DrillThroughActionCheckResult dtaResult = dtaExecutor.execute(); + result.getDrillThroughActionResults().add(dtaResult); + + if (dtaResult.getStatus() == CheckStatus.FAILURE) { + result.setStatus(CheckStatus.FAILURE); + } + } + + } catch (Exception e) { + result.setStatus(CheckStatus.FAILURE); + } + + result.setEndTime(new Date()); + result.setExecutionTimeMs(System.currentTimeMillis() - startTime); + + return result; + } + + private Optional findCube() { + String cubeName = check.getCubeName(); + String cubeUniqueName = check.getCubeUniqueName(); + + return cubes.stream() + .filter(c -> { + if (cubeUniqueName != null && !cubeUniqueName.isEmpty()) { + return cubeUniqueName.equals(c.getUniqueName()); + } + return cubeName != null && cubeName.equals(c.getName()); + }) + .findFirst(); + } + + private AttributeCheckResult executeAttributeCheck(CubeAttributeCheck attrCheck, Cube cube) { + AttributeCheckResult result = factory.createAttributeCheckResult(); + result.setCheckName(attrCheck.getName()); + result.setAttributeName(attrCheck.getAttributeType().getName()); + result.setExpectedValue(attrCheck.getExpectedValue()); + + String actualValue = getCubeAttributeValue(cube, attrCheck.getAttributeType()); + result.setActualValue(actualValue); + + boolean matches; + if (attrCheck.getAttributeType() == CubeAttribute.VISIBLE) { + // Boolean comparison + Boolean expectedBool = attrCheck.getExpectedBoolean(); + Boolean actualBool = cube.isVisible(); + matches = AttributeCheckHelper.compareBooleans(expectedBool, actualBool); + } else { + // String comparison + matches = AttributeCheckHelper.compareValues( + attrCheck.getExpectedValue(), + actualValue, + attrCheck.getMatchMode(), + attrCheck.isCaseSensitive() + ); + } + + result.setStatus(matches ? CheckStatus.SUCCESS : CheckStatus.FAILURE); + return result; + } + + private String getCubeAttributeValue(Cube cube, CubeAttribute attributeType) { + return switch (attributeType) { + case NAME -> cube.getName(); + case UNIQUE_NAME -> cube.getUniqueName(); + case CAPTION -> cube.getCaption(); + case DESCRIPTION -> cube.getDescription(); + case VISIBLE -> String.valueOf(cube.isVisible()); + case CUBE_TYPE -> cube.getClass().getSimpleName(); + }; + } +} diff --git a/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/DatabaseColumnCheckExecutor.java b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/DatabaseColumnCheckExecutor.java new file mode 100644 index 0000000..9928441 --- /dev/null +++ b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/DatabaseColumnCheckExecutor.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.runtime.impl.executors; + +import java.util.Date; +import java.util.List; +import java.util.Optional; + +import org.eclipse.daanse.olap.api.element.DatabaseColumn; +import org.eclipse.daanse.olap.check.model.check.AttributeCheckResult; +import org.eclipse.daanse.olap.check.model.check.CheckStatus; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnAttribute; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnCheckResult; +import org.eclipse.daanse.olap.check.model.check.OlapCheckFactory; + +/** + * Executor for DatabaseColumnCheck that verifies database column existence and attributes. + */ +public class DatabaseColumnCheckExecutor { + + private final DatabaseColumnCheck check; + private final List columns; + private final OlapCheckFactory factory; + + public DatabaseColumnCheckExecutor(DatabaseColumnCheck check, List columns, OlapCheckFactory factory) { + this.check = check; + this.columns = columns; + this.factory = factory; + } + + public DatabaseColumnCheckResult execute() { + long startTime = System.currentTimeMillis(); + Date start = new Date(); + + DatabaseColumnCheckResult result = factory.createDatabaseColumnCheckResult(); + result.setCheckName(check.getName()); + result.setCheckDescription(check.getDescription()); + result.setColumnName(check.getColumnName()); + result.setStartTime(start); + result.setSourceCheck(check); + + try { + // Find the column + Optional foundColumn = findColumn(); + + if (foundColumn.isEmpty()) { + result.setStatus(CheckStatus.FAILURE); + result.setEndTime(new Date()); + result.setExecutionTimeMs(System.currentTimeMillis() - startTime); + return result; + } + + DatabaseColumn column = foundColumn.get(); + result.setStatus(CheckStatus.SUCCESS); + + // Execute attribute checks + for (DatabaseColumnAttributeCheck attrCheck : check.getColumnAttributeChecks()) { + AttributeCheckResult attrResult = executeAttributeCheck(attrCheck, column); + result.getAttributeResults().add(attrResult); + if (attrResult.getStatus() == CheckStatus.FAILURE) { + result.setStatus(CheckStatus.FAILURE); + } + } + + } catch (Exception e) { + result.setStatus(CheckStatus.FAILURE); + } + + result.setEndTime(new Date()); + result.setExecutionTimeMs(System.currentTimeMillis() - startTime); + + return result; + } + + private Optional findColumn() { + String columnName = check.getColumnName(); + + return columns.stream() + .filter(c -> columnName != null && columnName.equals(c.getName())) + .findFirst(); + } + + private AttributeCheckResult executeAttributeCheck(DatabaseColumnAttributeCheck attrCheck, DatabaseColumn column) { + AttributeCheckResult result = factory.createAttributeCheckResult(); + result.setCheckName(attrCheck.getName()); + result.setAttributeName(attrCheck.getAttributeType().getName()); + result.setExpectedValue(attrCheck.getExpectedValue()); + + String actualValue = getColumnAttributeValue(column, attrCheck.getAttributeType()); + result.setActualValue(actualValue); + + boolean matches; + if (attrCheck.getAttributeType() == DatabaseColumnAttribute.NULLABLE) { + Boolean expectedBool = attrCheck.getExpectedBoolean(); + Boolean actualBool = column.getNullable(); + matches = AttributeCheckHelper.compareBooleans(expectedBool, actualBool); + } else if (attrCheck.getAttributeType() == DatabaseColumnAttribute.COLUMN_SIZE || + attrCheck.getAttributeType() == DatabaseColumnAttribute.DECIMAL_DIGITS) { + Integer expectedInt = attrCheck.getExpectedInt(); + Integer actualInt = getColumnIntAttribute(column, attrCheck.getAttributeType()); + matches = AttributeCheckHelper.compareInts(expectedInt, actualInt); + } else { + matches = AttributeCheckHelper.compareValues( + attrCheck.getExpectedValue(), + actualValue, + attrCheck.getMatchMode(), + attrCheck.isCaseSensitive() + ); + } + + result.setStatus(matches ? CheckStatus.SUCCESS : CheckStatus.FAILURE); + return result; + } + + private String getColumnAttributeValue(DatabaseColumn column, DatabaseColumnAttribute attributeType) { + return switch (attributeType) { + case NAME -> column.getName(); + case TYPE -> column.getType() != null ? column.getType().name() : null; + case NULLABLE -> String.valueOf(column.getNullable()); + case COLUMN_SIZE -> String.valueOf(column.getColumnSize()); + case DECIMAL_DIGITS -> String.valueOf(column.getDecimalDigits()); + }; + } + + private Integer getColumnIntAttribute(DatabaseColumn column, DatabaseColumnAttribute attributeType) { + return switch (attributeType) { + case COLUMN_SIZE -> column.getColumnSize(); + case DECIMAL_DIGITS -> column.getDecimalDigits(); + default -> null; + }; + } +} diff --git a/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/DatabaseSchemaCheckExecutor.java b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/DatabaseSchemaCheckExecutor.java new file mode 100644 index 0000000..20d0966 --- /dev/null +++ b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/DatabaseSchemaCheckExecutor.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.runtime.impl.executors; + +import java.util.Date; +import java.util.List; +import java.util.Optional; + +import org.eclipse.daanse.olap.api.element.DatabaseSchema; +import org.eclipse.daanse.olap.api.element.DatabaseTable; +import org.eclipse.daanse.olap.check.model.check.AttributeCheckResult; +import org.eclipse.daanse.olap.check.model.check.CheckStatus; +import org.eclipse.daanse.olap.check.model.check.DatabaseSchemaAttribute; +import org.eclipse.daanse.olap.check.model.check.DatabaseSchemaAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseSchemaCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseSchemaCheckResult; +import org.eclipse.daanse.olap.check.model.check.DatabaseTableCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseTableCheckResult; +import org.eclipse.daanse.olap.check.model.check.OlapCheckFactory; + +/** + * Executor for DatabaseSchemaCheck that verifies database schema existence and structure. + */ +public class DatabaseSchemaCheckExecutor { + + private final DatabaseSchemaCheck check; + private final List schemas; + private final OlapCheckFactory factory; + + public DatabaseSchemaCheckExecutor(DatabaseSchemaCheck check, List schemas, OlapCheckFactory factory) { + this.check = check; + this.schemas = schemas; + this.factory = factory; + } + + public DatabaseSchemaCheckResult execute() { + long startTime = System.currentTimeMillis(); + Date start = new Date(); + + DatabaseSchemaCheckResult result = factory.createDatabaseSchemaCheckResult(); + result.setCheckName(check.getName()); + result.setCheckDescription(check.getDescription()); + result.setSchemaName(check.getSchemaName()); + result.setStartTime(start); + result.setSourceCheck(check); + + try { + // Find the schema + Optional foundSchema = findSchema(); + + if (foundSchema.isEmpty()) { + result.setStatus(CheckStatus.FAILURE); + result.setEndTime(new Date()); + result.setExecutionTimeMs(System.currentTimeMillis() - startTime); + return result; + } + + DatabaseSchema schema = foundSchema.get(); + result.setStatus(CheckStatus.SUCCESS); + + // Execute attribute checks + for (DatabaseSchemaAttributeCheck attrCheck : check.getSchemaAttributeChecks()) { + AttributeCheckResult attrResult = executeAttributeCheck(attrCheck, schema); + result.getAttributeResults().add(attrResult); + if (attrResult.getStatus() == CheckStatus.FAILURE) { + result.setStatus(CheckStatus.FAILURE); + } + } + + // Execute table checks + List tables = schema.getDbTables(); + for (DatabaseTableCheck tableCheck : check.getTableChecks()) { + if (!tableCheck.isEnabled()) { + continue; + } + + DatabaseTableCheckExecutor tableExecutor = new DatabaseTableCheckExecutor( + tableCheck, tables, factory + ); + DatabaseTableCheckResult tableResult = tableExecutor.execute(); + result.getTableResults().add(tableResult); + + if (tableResult.getStatus() == CheckStatus.FAILURE) { + result.setStatus(CheckStatus.FAILURE); + } + } + + } catch (Exception e) { + result.setStatus(CheckStatus.FAILURE); + } + + result.setEndTime(new Date()); + result.setExecutionTimeMs(System.currentTimeMillis() - startTime); + + return result; + } + + private Optional findSchema() { + String schemaName = check.getSchemaName(); + + return schemas.stream() + .filter(s -> schemaName != null && schemaName.equals(s.getName())) + .findFirst(); + } + + private AttributeCheckResult executeAttributeCheck(DatabaseSchemaAttributeCheck attrCheck, DatabaseSchema schema) { + AttributeCheckResult result = factory.createAttributeCheckResult(); + result.setCheckName(attrCheck.getName()); + result.setAttributeName(attrCheck.getAttributeType().getName()); + result.setExpectedValue(attrCheck.getExpectedValue()); + + String actualValue = getSchemaAttributeValue(schema, attrCheck.getAttributeType()); + result.setActualValue(actualValue); + + boolean matches = AttributeCheckHelper.compareValues( + attrCheck.getExpectedValue(), + actualValue, + attrCheck.getMatchMode(), + attrCheck.isCaseSensitive() + ); + + result.setStatus(matches ? CheckStatus.SUCCESS : CheckStatus.FAILURE); + return result; + } + + private String getSchemaAttributeValue(DatabaseSchema schema, DatabaseSchemaAttribute attributeType) { + return switch (attributeType) { + case NAME -> schema.getName(); + }; + } +} diff --git a/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/DatabaseTableCheckExecutor.java b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/DatabaseTableCheckExecutor.java new file mode 100644 index 0000000..c913876 --- /dev/null +++ b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/DatabaseTableCheckExecutor.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.runtime.impl.executors; + +import java.util.Date; +import java.util.List; +import java.util.Optional; + +import org.eclipse.daanse.olap.api.element.DatabaseColumn; +import org.eclipse.daanse.olap.api.element.DatabaseTable; +import org.eclipse.daanse.olap.check.model.check.AttributeCheckResult; +import org.eclipse.daanse.olap.check.model.check.CheckStatus; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseColumnCheckResult; +import org.eclipse.daanse.olap.check.model.check.DatabaseTableAttribute; +import org.eclipse.daanse.olap.check.model.check.DatabaseTableAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseTableCheck; +import org.eclipse.daanse.olap.check.model.check.DatabaseTableCheckResult; +import org.eclipse.daanse.olap.check.model.check.OlapCheckFactory; + +/** + * Executor for DatabaseTableCheck that verifies database table existence and structure. + */ +public class DatabaseTableCheckExecutor { + + private final DatabaseTableCheck check; + private final List tables; + private final OlapCheckFactory factory; + + public DatabaseTableCheckExecutor(DatabaseTableCheck check, List tables, OlapCheckFactory factory) { + this.check = check; + this.tables = tables; + this.factory = factory; + } + + public DatabaseTableCheckResult execute() { + long startTime = System.currentTimeMillis(); + Date start = new Date(); + + DatabaseTableCheckResult result = factory.createDatabaseTableCheckResult(); + result.setCheckName(check.getName()); + result.setCheckDescription(check.getDescription()); + result.setTableName(check.getTableName()); + result.setStartTime(start); + result.setSourceCheck(check); + + try { + // Find the table + Optional foundTable = findTable(); + + if (foundTable.isEmpty()) { + result.setStatus(CheckStatus.FAILURE); + result.setEndTime(new Date()); + result.setExecutionTimeMs(System.currentTimeMillis() - startTime); + return result; + } + + DatabaseTable table = foundTable.get(); + result.setStatus(CheckStatus.SUCCESS); + + // Execute attribute checks + for (DatabaseTableAttributeCheck attrCheck : check.getTableAttributeChecks()) { + AttributeCheckResult attrResult = executeAttributeCheck(attrCheck, table); + result.getAttributeResults().add(attrResult); + if (attrResult.getStatus() == CheckStatus.FAILURE) { + result.setStatus(CheckStatus.FAILURE); + } + } + + // Execute column checks + List columns = table.getDbColumns(); + for (DatabaseColumnCheck columnCheck : check.getColumnChecks()) { + if (!columnCheck.isEnabled()) { + continue; + } + + DatabaseColumnCheckExecutor columnExecutor = new DatabaseColumnCheckExecutor( + columnCheck, columns, factory + ); + DatabaseColumnCheckResult columnResult = columnExecutor.execute(); + result.getColumnResults().add(columnResult); + + if (columnResult.getStatus() == CheckStatus.FAILURE) { + result.setStatus(CheckStatus.FAILURE); + } + } + + } catch (Exception e) { + result.setStatus(CheckStatus.FAILURE); + } + + result.setEndTime(new Date()); + result.setExecutionTimeMs(System.currentTimeMillis() - startTime); + + return result; + } + + private Optional findTable() { + String tableName = check.getTableName(); + + return tables.stream() + .filter(t -> tableName != null && tableName.equals(t.getName())) + .findFirst(); + } + + private AttributeCheckResult executeAttributeCheck(DatabaseTableAttributeCheck attrCheck, DatabaseTable table) { + AttributeCheckResult result = factory.createAttributeCheckResult(); + result.setCheckName(attrCheck.getName()); + result.setAttributeName(attrCheck.getAttributeType().getName()); + result.setExpectedValue(attrCheck.getExpectedValue()); + + String actualValue = getTableAttributeValue(table, attrCheck.getAttributeType()); + result.setActualValue(actualValue); + + boolean matches = AttributeCheckHelper.compareValues( + attrCheck.getExpectedValue(), + actualValue, + attrCheck.getMatchMode(), + attrCheck.isCaseSensitive() + ); + + result.setStatus(matches ? CheckStatus.SUCCESS : CheckStatus.FAILURE); + return result; + } + + private String getTableAttributeValue(DatabaseTable table, DatabaseTableAttribute attributeType) { + return switch (attributeType) { + case NAME -> table.getName(); + case DESCRIPTION -> table.getDescription(); + }; + } +} diff --git a/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/DimensionCheckExecutor.java b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/DimensionCheckExecutor.java new file mode 100644 index 0000000..f177816 --- /dev/null +++ b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/DimensionCheckExecutor.java @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.runtime.impl.executors; + +import java.util.Date; +import java.util.List; +import java.util.Optional; + +import org.eclipse.daanse.olap.api.CatalogReader; +import org.eclipse.daanse.olap.api.connection.Connection; +import org.eclipse.daanse.olap.api.element.Cube; +import org.eclipse.daanse.olap.api.element.Dimension; +import org.eclipse.daanse.olap.api.element.Hierarchy; +import org.eclipse.daanse.olap.check.model.check.AttributeCheckResult; +import org.eclipse.daanse.olap.check.model.check.CheckStatus; +import org.eclipse.daanse.olap.check.model.check.DimensionAttribute; +import org.eclipse.daanse.olap.check.model.check.DimensionAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.DimensionCheck; +import org.eclipse.daanse.olap.check.model.check.DimensionCheckResult; +import org.eclipse.daanse.olap.check.model.check.HierarchyCheck; +import org.eclipse.daanse.olap.check.model.check.HierarchyCheckResult; +import org.eclipse.daanse.olap.check.model.check.OlapCheckFactory; + +/** + * Executor for DimensionCheck that verifies dimension existence and structure. + */ +public class DimensionCheckExecutor { + + private final DimensionCheck check; + private final List dimensions; + private final Cube cube; + private final CatalogReader catalogReader; + private final Connection connection; + private final OlapCheckFactory factory; + + public DimensionCheckExecutor(DimensionCheck check, List dimensions, Cube cube, + CatalogReader catalogReader, Connection connection, OlapCheckFactory factory) { + this.check = check; + this.dimensions = dimensions; + this.cube = cube; + this.catalogReader = catalogReader; + this.connection = connection; + this.factory = factory; + } + + public DimensionCheckResult execute() { + long startTime = System.currentTimeMillis(); + Date start = new Date(); + + DimensionCheckResult result = factory.createDimensionCheckResult(); + result.setCheckName(check.getName()); + result.setCheckDescription(check.getDescription()); + result.setDimensionName(check.getDimensionName()); + result.setStartTime(start); + result.setSourceCheck(check); + + try { + // Find the dimension + Optional foundDimension = findDimension(); + + if (foundDimension.isEmpty()) { + result.setStatus(CheckStatus.FAILURE); + result.setEndTime(new Date()); + result.setExecutionTimeMs(System.currentTimeMillis() - startTime); + return result; + } + + Dimension dimension = foundDimension.get(); + result.setDimensionUniqueName(dimension.getUniqueName()); + result.setStatus(CheckStatus.SUCCESS); + + // Execute attribute checks + for (DimensionAttributeCheck attrCheck : check.getDimensionAttributeChecks()) { + AttributeCheckResult attrResult = executeAttributeCheck(attrCheck, dimension); + result.getAttributeResults().add(attrResult); + if (attrResult.getStatus() == CheckStatus.FAILURE) { + result.setStatus(CheckStatus.FAILURE); + } + } + + // Execute hierarchy checks + List hierarchies = catalogReader.getDimensionHierarchies(dimension); + for (HierarchyCheck hierarchyCheck : check.getHierarchyChecks()) { + if (!hierarchyCheck.isEnabled()) { + continue; + } + + HierarchyCheckExecutor hierExecutor = new HierarchyCheckExecutor( + hierarchyCheck, hierarchies, cube, catalogReader, connection, factory + ); + HierarchyCheckResult hierResult = hierExecutor.execute(); + result.getHierarchyResults().add(hierResult); + + if (hierResult.getStatus() == CheckStatus.FAILURE) { + result.setStatus(CheckStatus.FAILURE); + } + } + + } catch (Exception e) { + result.setStatus(CheckStatus.FAILURE); + } + + result.setEndTime(new Date()); + result.setExecutionTimeMs(System.currentTimeMillis() - startTime); + + return result; + } + + private Optional findDimension() { + String dimensionName = check.getDimensionName(); + String dimensionUniqueName = check.getDimensionUniqueName(); + + return dimensions.stream() + .filter(d -> { + if (dimensionUniqueName != null && !dimensionUniqueName.isEmpty()) { + return dimensionUniqueName.equals(d.getUniqueName()); + } + return dimensionName != null && dimensionName.equals(d.getName()); + }) + .findFirst(); + } + + private AttributeCheckResult executeAttributeCheck(DimensionAttributeCheck attrCheck, Dimension dimension) { + AttributeCheckResult result = factory.createAttributeCheckResult(); + result.setCheckName(attrCheck.getName()); + result.setAttributeName(attrCheck.getAttributeType().getName()); + result.setExpectedValue(attrCheck.getExpectedValue()); + + String actualValue = getDimensionAttributeValue(dimension, attrCheck.getAttributeType()); + result.setActualValue(actualValue); + + boolean matches; + if (attrCheck.getAttributeType() == DimensionAttribute.VISIBLE || + attrCheck.getAttributeType() == DimensionAttribute.IS_VIRTUAL) { + Boolean expectedBool = attrCheck.getExpectedBoolean(); + Boolean actualBool = getDimensionBooleanAttribute(dimension, attrCheck.getAttributeType()); + matches = AttributeCheckHelper.compareBooleans(expectedBool, actualBool); + } else if (attrCheck.getAttributeType() == DimensionAttribute.ORDINAL || + attrCheck.getAttributeType() == DimensionAttribute.CARDINALITY) { + Integer expectedInt = attrCheck.getExpectedInt(); + Integer actualInt = getDimensionIntAttribute(dimension, attrCheck.getAttributeType()); + matches = AttributeCheckHelper.compareInts(expectedInt, actualInt); + } else { + matches = AttributeCheckHelper.compareValues( + attrCheck.getExpectedValue(), + actualValue, + attrCheck.getMatchMode(), + attrCheck.isCaseSensitive() + ); + } + + result.setStatus(matches ? CheckStatus.SUCCESS : CheckStatus.FAILURE); + return result; + } + + private String getDimensionAttributeValue(Dimension dimension, DimensionAttribute attributeType) { + return switch (attributeType) { + case NAME -> dimension.getName(); + case UNIQUE_NAME -> dimension.getUniqueName(); + case CAPTION -> dimension.getCaption(); + case DESCRIPTION -> dimension.getDescription(); + case VISIBLE -> String.valueOf(dimension.isVisible()); + case DIMENSION_TYPE -> dimension.getDimensionType() != null ? dimension.getDimensionType().name() : null; + case ORDINAL -> "0"; // Ordinal not directly available on Dimension + case IS_VIRTUAL -> "false"; + case CARDINALITY -> "0"; + }; + } + + private Boolean getDimensionBooleanAttribute(Dimension dimension, DimensionAttribute attributeType) { + return switch (attributeType) { + case VISIBLE -> dimension.isVisible(); + case IS_VIRTUAL -> false; + default -> null; + }; + } + + private Integer getDimensionIntAttribute(Dimension dimension, DimensionAttribute attributeType) { + return switch (attributeType) { + case ORDINAL -> 0; // Ordinal not directly available on Dimension + case CARDINALITY -> 0; + default -> null; + }; + } +} diff --git a/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/DrillThroughActionCheckExecutor.java b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/DrillThroughActionCheckExecutor.java new file mode 100644 index 0000000..fcaa1ab --- /dev/null +++ b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/DrillThroughActionCheckExecutor.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.runtime.impl.executors; + +import java.util.Date; +import java.util.List; +import java.util.Optional; + +import org.eclipse.daanse.olap.api.element.DrillThroughAction; +import org.eclipse.daanse.olap.check.model.check.AttributeCheckResult; +import org.eclipse.daanse.olap.check.model.check.CheckStatus; +import org.eclipse.daanse.olap.check.model.check.DrillThroughActionAttribute; +import org.eclipse.daanse.olap.check.model.check.DrillThroughActionAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.DrillThroughActionCheck; +import org.eclipse.daanse.olap.check.model.check.DrillThroughActionCheckResult; +import org.eclipse.daanse.olap.check.model.check.OlapCheckFactory; + +/** + * Executor for DrillThroughActionCheck that verifies drill-through action existence and attributes. + */ +public class DrillThroughActionCheckExecutor { + + private final DrillThroughActionCheck check; + private final List actions; + private final OlapCheckFactory factory; + + public DrillThroughActionCheckExecutor(DrillThroughActionCheck check, List actions, OlapCheckFactory factory) { + this.check = check; + this.actions = actions; + this.factory = factory; + } + + public DrillThroughActionCheckResult execute() { + long startTime = System.currentTimeMillis(); + Date start = new Date(); + + DrillThroughActionCheckResult result = factory.createDrillThroughActionCheckResult(); + result.setCheckName(check.getName()); + result.setCheckDescription(check.getDescription()); + result.setActionName(check.getActionName()); + result.setStartTime(start); + result.setSourceCheck(check); + + try { + // Find the DrillThroughAction + Optional foundAction = findAction(); + + if (foundAction.isEmpty()) { + result.setStatus(CheckStatus.FAILURE); + result.setEndTime(new Date()); + result.setExecutionTimeMs(System.currentTimeMillis() - startTime); + return result; + } + + DrillThroughAction action = foundAction.get(); + result.setStatus(CheckStatus.SUCCESS); + + // Execute attribute checks + for (DrillThroughActionAttributeCheck attrCheck : check.getActionAttributeChecks()) { + AttributeCheckResult attrResult = executeAttributeCheck(attrCheck, action); + result.getAttributeResults().add(attrResult); + if (attrResult.getStatus() == CheckStatus.FAILURE) { + result.setStatus(CheckStatus.FAILURE); + } + } + + } catch (Exception e) { + result.setStatus(CheckStatus.FAILURE); + } + + result.setEndTime(new Date()); + result.setExecutionTimeMs(System.currentTimeMillis() - startTime); + + return result; + } + + private Optional findAction() { + String actionName = check.getActionName(); + + return actions.stream() + .filter(a -> actionName != null && actionName.equals(a.getName())) + .findFirst(); + } + + private AttributeCheckResult executeAttributeCheck(DrillThroughActionAttributeCheck attrCheck, DrillThroughAction action) { + AttributeCheckResult result = factory.createAttributeCheckResult(); + result.setCheckName(attrCheck.getName()); + result.setAttributeName(attrCheck.getAttributeType().getName()); + result.setExpectedValue(attrCheck.getExpectedValue()); + + String actualValue = getActionAttributeValue(action, attrCheck.getAttributeType()); + result.setActualValue(actualValue); + + boolean matches; + if (attrCheck.getAttributeType() == DrillThroughActionAttribute.IS_DEFAULT) { + Boolean expectedBool = attrCheck.getExpectedBoolean(); + Boolean actualBool = action.getIsDefault(); + matches = AttributeCheckHelper.compareBooleans(expectedBool, actualBool); + } else { + matches = AttributeCheckHelper.compareValues( + attrCheck.getExpectedValue(), + actualValue, + attrCheck.getMatchMode(), + attrCheck.isCaseSensitive() + ); + } + + result.setStatus(matches ? CheckStatus.SUCCESS : CheckStatus.FAILURE); + return result; + } + + private String getActionAttributeValue(DrillThroughAction action, DrillThroughActionAttribute attributeType) { + return switch (attributeType) { + case NAME -> action.getName(); + case CAPTION -> action.getCaption(); + case DESCRIPTION -> action.getDescription(); + case IS_DEFAULT -> String.valueOf(action.getIsDefault()); + }; + } +} diff --git a/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/HierarchyCheckExecutor.java b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/HierarchyCheckExecutor.java new file mode 100644 index 0000000..46ce8d1 --- /dev/null +++ b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/HierarchyCheckExecutor.java @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.runtime.impl.executors; + +import java.util.Date; +import java.util.List; +import java.util.Optional; + +import org.eclipse.daanse.olap.api.CatalogReader; +import org.eclipse.daanse.olap.api.connection.Connection; +import org.eclipse.daanse.olap.api.element.Cube; +import org.eclipse.daanse.olap.api.element.Hierarchy; +import org.eclipse.daanse.olap.api.element.Level; +import org.eclipse.daanse.olap.api.element.Member; +import org.eclipse.daanse.olap.check.model.check.AttributeCheckResult; +import org.eclipse.daanse.olap.check.model.check.CheckStatus; +import org.eclipse.daanse.olap.check.model.check.HierarchyAttribute; +import org.eclipse.daanse.olap.check.model.check.HierarchyAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.HierarchyCheck; +import org.eclipse.daanse.olap.check.model.check.HierarchyCheckResult; +import org.eclipse.daanse.olap.check.model.check.LevelCheck; +import org.eclipse.daanse.olap.check.model.check.LevelCheckResult; +import org.eclipse.daanse.olap.check.model.check.OlapCheckFactory; + +/** + * Executor for HierarchyCheck that verifies hierarchy existence and structure. + */ +public class HierarchyCheckExecutor { + + private final HierarchyCheck check; + private final List hierarchies; + private final Cube cube; + private final CatalogReader catalogReader; + private final Connection connection; + private final OlapCheckFactory factory; + + public HierarchyCheckExecutor(HierarchyCheck check, List hierarchies, Cube cube, + CatalogReader catalogReader, Connection connection, OlapCheckFactory factory) { + this.check = check; + this.hierarchies = hierarchies; + this.cube = cube; + this.catalogReader = catalogReader; + this.connection = connection; + this.factory = factory; + } + + public HierarchyCheckResult execute() { + long startTime = System.currentTimeMillis(); + Date start = new Date(); + + HierarchyCheckResult result = factory.createHierarchyCheckResult(); + result.setCheckName(check.getName()); + result.setCheckDescription(check.getDescription()); + result.setHierarchyName(check.getHierarchyName()); + result.setStartTime(start); + result.setSourceCheck(check); + + try { + // Find the hierarchy + Optional foundHierarchy = findHierarchy(); + + if (foundHierarchy.isEmpty()) { + result.setStatus(CheckStatus.FAILURE); + result.setEndTime(new Date()); + result.setExecutionTimeMs(System.currentTimeMillis() - startTime); + return result; + } + + Hierarchy hierarchy = foundHierarchy.get(); + result.setHierarchyUniqueName(hierarchy.getUniqueName()); + result.setStatus(CheckStatus.SUCCESS); + + // Execute attribute checks + for (HierarchyAttributeCheck attrCheck : check.getHierarchyAttributeChecks()) { + AttributeCheckResult attrResult = executeAttributeCheck(attrCheck, hierarchy); + result.getAttributeResults().add(attrResult); + if (attrResult.getStatus() == CheckStatus.FAILURE) { + result.setStatus(CheckStatus.FAILURE); + } + } + + // Execute level checks + List levels = catalogReader.getHierarchyLevels(hierarchy); + for (LevelCheck levelCheck : check.getLevelChecks()) { + if (!levelCheck.isEnabled()) { + continue; + } + + LevelCheckExecutor levelExecutor = new LevelCheckExecutor( + levelCheck, levels, cube, catalogReader, connection, factory + ); + LevelCheckResult levelResult = levelExecutor.execute(); + result.getLevelResults().add(levelResult); + + if (levelResult.getStatus() == CheckStatus.FAILURE) { + result.setStatus(CheckStatus.FAILURE); + } + } + + } catch (Exception e) { + result.setStatus(CheckStatus.FAILURE); + } + + result.setEndTime(new Date()); + result.setExecutionTimeMs(System.currentTimeMillis() - startTime); + + return result; + } + + private Optional findHierarchy() { + String hierarchyName = check.getHierarchyName(); + String hierarchyUniqueName = check.getHierarchyUniqueName(); + + return hierarchies.stream() + .filter(h -> { + if (hierarchyUniqueName != null && !hierarchyUniqueName.isEmpty()) { + return hierarchyUniqueName.equals(h.getUniqueName()); + } + return hierarchyName != null && hierarchyName.equals(h.getName()); + }) + .findFirst(); + } + + private AttributeCheckResult executeAttributeCheck(HierarchyAttributeCheck attrCheck, Hierarchy hierarchy) { + AttributeCheckResult result = factory.createAttributeCheckResult(); + result.setCheckName(attrCheck.getName()); + result.setAttributeName(attrCheck.getAttributeType().getName()); + result.setExpectedValue(attrCheck.getExpectedValue()); + + String actualValue = getHierarchyAttributeValue(hierarchy, attrCheck.getAttributeType()); + result.setActualValue(actualValue); + + boolean matches; + if (attrCheck.getAttributeType() == HierarchyAttribute.VISIBLE || + attrCheck.getAttributeType() == HierarchyAttribute.HAS_ALL) { + Boolean expectedBool = attrCheck.getExpectedBoolean(); + Boolean actualBool = getHierarchyBooleanAttribute(hierarchy, attrCheck.getAttributeType()); + matches = AttributeCheckHelper.compareBooleans(expectedBool, actualBool); + } else if (attrCheck.getAttributeType() == HierarchyAttribute.CARDINALITY) { + Integer expectedInt = attrCheck.getExpectedInt(); + Integer actualInt = getHierarchyIntAttribute(hierarchy, attrCheck.getAttributeType()); + matches = AttributeCheckHelper.compareInts(expectedInt, actualInt); + } else { + matches = AttributeCheckHelper.compareValues( + attrCheck.getExpectedValue(), + actualValue, + attrCheck.getMatchMode(), + attrCheck.isCaseSensitive() + ); + } + + result.setStatus(matches ? CheckStatus.SUCCESS : CheckStatus.FAILURE); + return result; + } + + private String getHierarchyAttributeValue(Hierarchy hierarchy, HierarchyAttribute attributeType) { + return switch (attributeType) { + case NAME -> hierarchy.getName(); + case UNIQUE_NAME -> hierarchy.getUniqueName(); + case CAPTION -> hierarchy.getCaption(); + case DESCRIPTION -> hierarchy.getDescription(); + case VISIBLE -> String.valueOf(hierarchy.isVisible()); + case HAS_ALL -> String.valueOf(hierarchy.hasAll()); + case ALL_MEMBER_NAME -> { + Member allMember = hierarchy.getAllMember(); + yield allMember != null ? allMember.getName() : null; + } + case ALL_MEMBER_UNIQUE_NAME -> { + Member allMember = hierarchy.getAllMember(); + yield allMember != null ? allMember.getUniqueName() : null; + } + case DEFAULT_MEMBER -> { + Member defaultMember = hierarchy.getDefaultMember(); + yield defaultMember != null ? defaultMember.getUniqueName() : null; + } + case DISPLAY_FOLDER -> hierarchy.getDisplayFolder(); + case ORIGIN -> ""; // Not typically available + case CARDINALITY -> "0"; // Would need to calculate + }; + } + + private Boolean getHierarchyBooleanAttribute(Hierarchy hierarchy, HierarchyAttribute attributeType) { + return switch (attributeType) { + case VISIBLE -> hierarchy.isVisible(); + case HAS_ALL -> hierarchy.hasAll(); + default -> null; + }; + } + + private Integer getHierarchyIntAttribute(Hierarchy hierarchy, HierarchyAttribute attributeType) { + return switch (attributeType) { + case CARDINALITY -> 0; // Would need to calculate + default -> null; + }; + } +} diff --git a/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/KPICheckExecutor.java b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/KPICheckExecutor.java new file mode 100644 index 0000000..e5956f2 --- /dev/null +++ b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/KPICheckExecutor.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.runtime.impl.executors; + +import java.util.Date; +import java.util.List; +import java.util.Optional; + +import org.eclipse.daanse.olap.api.element.KPI; +import org.eclipse.daanse.olap.check.model.check.AttributeCheckResult; +import org.eclipse.daanse.olap.check.model.check.CheckStatus; +import org.eclipse.daanse.olap.check.model.check.KPIAttribute; +import org.eclipse.daanse.olap.check.model.check.KPIAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.KPICheck; +import org.eclipse.daanse.olap.check.model.check.KPICheckResult; +import org.eclipse.daanse.olap.check.model.check.OlapCheckFactory; + +/** + * Executor for KPICheck that verifies KPI existence and attributes. + */ +public class KPICheckExecutor { + + private final KPICheck check; + private final List kpis; + private final OlapCheckFactory factory; + + public KPICheckExecutor(KPICheck check, List kpis, OlapCheckFactory factory) { + this.check = check; + this.kpis = kpis; + this.factory = factory; + } + + public KPICheckResult execute() { + long startTime = System.currentTimeMillis(); + Date start = new Date(); + + KPICheckResult result = factory.createKPICheckResult(); + result.setCheckName(check.getName()); + result.setCheckDescription(check.getDescription()); + result.setKpiName(check.getKpiName()); + result.setStartTime(start); + result.setSourceCheck(check); + + try { + // Find the KPI + Optional foundKpi = findKpi(); + + if (foundKpi.isEmpty()) { + result.setStatus(CheckStatus.FAILURE); + result.setEndTime(new Date()); + result.setExecutionTimeMs(System.currentTimeMillis() - startTime); + return result; + } + + KPI kpi = foundKpi.get(); + result.setStatus(CheckStatus.SUCCESS); + + // Execute attribute checks + for (KPIAttributeCheck attrCheck : check.getKpiAttributeChecks()) { + AttributeCheckResult attrResult = executeAttributeCheck(attrCheck, kpi); + result.getAttributeResults().add(attrResult); + if (attrResult.getStatus() == CheckStatus.FAILURE) { + result.setStatus(CheckStatus.FAILURE); + } + } + + } catch (Exception e) { + result.setStatus(CheckStatus.FAILURE); + } + + result.setEndTime(new Date()); + result.setExecutionTimeMs(System.currentTimeMillis() - startTime); + + return result; + } + + private Optional findKpi() { + String kpiName = check.getKpiName(); + + return kpis.stream() + .filter(k -> kpiName != null && kpiName.equals(k.getName())) + .findFirst(); + } + + private AttributeCheckResult executeAttributeCheck(KPIAttributeCheck attrCheck, KPI kpi) { + AttributeCheckResult result = factory.createAttributeCheckResult(); + result.setCheckName(attrCheck.getName()); + result.setAttributeName(attrCheck.getAttributeType().getName()); + result.setExpectedValue(attrCheck.getExpectedValue()); + + String actualValue = getKpiAttributeValue(kpi, attrCheck.getAttributeType()); + result.setActualValue(actualValue); + + boolean matches = AttributeCheckHelper.compareValues( + attrCheck.getExpectedValue(), + actualValue, + attrCheck.getMatchMode(), + attrCheck.isCaseSensitive() + ); + + result.setStatus(matches ? CheckStatus.SUCCESS : CheckStatus.FAILURE); + return result; + } + + private String getKpiAttributeValue(KPI kpi, KPIAttribute attributeType) { + return switch (attributeType) { + case NAME -> kpi.getName(); + case DESCRIPTION -> kpi.getDescription(); + case DISPLAY_FOLDER -> kpi.getDisplayFolder(); + case VALUE -> kpi.getValue(); + case GOAL -> kpi.getGoal(); + case STATUS -> kpi.getStatus(); + case TREND -> kpi.getTrend(); + case WEIGHT -> kpi.getWeight(); + case CURRENT_TIME_MEMBER -> kpi.getCurrentTimeMember(); + case STATUS_GRAPHIC -> kpi.getStatusGraphic(); + case TREND_GRAPHIC -> kpi.getTrendGraphic(); + case PARENT_KPI_NAME -> { + KPI parent = kpi.getParentKpi(); + yield parent != null ? parent.getName() : null; + } + }; + } +} diff --git a/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/LevelCheckExecutor.java b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/LevelCheckExecutor.java new file mode 100644 index 0000000..9888cee --- /dev/null +++ b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/LevelCheckExecutor.java @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.runtime.impl.executors; + +import java.util.Date; +import java.util.List; +import java.util.Optional; + +import org.eclipse.daanse.olap.api.CatalogReader; +import org.eclipse.daanse.olap.api.connection.Connection; +import org.eclipse.daanse.olap.api.element.Cube; +import org.eclipse.daanse.olap.api.element.Level; +import org.eclipse.daanse.olap.api.element.Member; +import org.eclipse.daanse.olap.check.model.check.AttributeCheckResult; +import org.eclipse.daanse.olap.check.model.check.CheckStatus; +import org.eclipse.daanse.olap.check.model.check.LevelAttribute; +import org.eclipse.daanse.olap.check.model.check.LevelAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.LevelCheck; +import org.eclipse.daanse.olap.check.model.check.LevelCheckResult; +import org.eclipse.daanse.olap.check.model.check.MemberCheck; +import org.eclipse.daanse.olap.check.model.check.MemberCheckResult; +import org.eclipse.daanse.olap.check.model.check.OlapCheckFactory; + +/** + * Executor for LevelCheck that verifies level existence and structure. + */ +public class LevelCheckExecutor { + + private final LevelCheck check; + private final List levels; + private final Cube cube; + private final CatalogReader catalogReader; + private final Connection connection; + private final OlapCheckFactory factory; + + public LevelCheckExecutor(LevelCheck check, List levels, Cube cube, + CatalogReader catalogReader, Connection connection, OlapCheckFactory factory) { + this.check = check; + this.levels = levels; + this.cube = cube; + this.catalogReader = catalogReader; + this.connection = connection; + this.factory = factory; + } + + public LevelCheckResult execute() { + long startTime = System.currentTimeMillis(); + Date start = new Date(); + + LevelCheckResult result = factory.createLevelCheckResult(); + result.setCheckName(check.getName()); + result.setCheckDescription(check.getDescription()); + result.setLevelName(check.getLevelName()); + result.setStartTime(start); + result.setSourceCheck(check); + + try { + // Find the level + Optional foundLevel = findLevel(); + + if (foundLevel.isEmpty()) { + result.setStatus(CheckStatus.FAILURE); + result.setEndTime(new Date()); + result.setExecutionTimeMs(System.currentTimeMillis() - startTime); + return result; + } + + Level level = foundLevel.get(); + result.setLevelUniqueName(level.getUniqueName()); + result.setStatus(CheckStatus.SUCCESS); + + // Execute attribute checks + for (LevelAttributeCheck attrCheck : check.getLevelAttributeChecks()) { + AttributeCheckResult attrResult = executeAttributeCheck(attrCheck, level); + result.getAttributeResults().add(attrResult); + if (attrResult.getStatus() == CheckStatus.FAILURE) { + result.setStatus(CheckStatus.FAILURE); + } + } + + // Execute member checks + List members = catalogReader.getLevelMembers(level, true); + for (MemberCheck memberCheck : check.getMemberChecks()) { + if (!memberCheck.isEnabled()) { + continue; + } + + MemberCheckExecutor memberExecutor = new MemberCheckExecutor( + memberCheck, members, cube, catalogReader, connection, factory + ); + MemberCheckResult memberResult = memberExecutor.execute(); + result.getMemberResults().add(memberResult); + + if (memberResult.getStatus() == CheckStatus.FAILURE) { + result.setStatus(CheckStatus.FAILURE); + } + } + + } catch (Exception e) { + result.setStatus(CheckStatus.FAILURE); + } + + result.setEndTime(new Date()); + result.setExecutionTimeMs(System.currentTimeMillis() - startTime); + + return result; + } + + private Optional findLevel() { + String levelName = check.getLevelName(); + String levelUniqueName = check.getLevelUniqueName(); + + return levels.stream() + .filter(l -> { + if (levelUniqueName != null && !levelUniqueName.isEmpty()) { + return levelUniqueName.equals(l.getUniqueName()); + } + return levelName != null && levelName.equals(l.getName()); + }) + .findFirst(); + } + + private AttributeCheckResult executeAttributeCheck(LevelAttributeCheck attrCheck, Level level) { + AttributeCheckResult result = factory.createAttributeCheckResult(); + result.setCheckName(attrCheck.getName()); + result.setAttributeName(attrCheck.getAttributeType().getName()); + result.setExpectedValue(attrCheck.getExpectedValue()); + + String actualValue = getLevelAttributeValue(level, attrCheck.getAttributeType()); + result.setActualValue(actualValue); + + boolean matches; + if (attrCheck.getAttributeType() == LevelAttribute.VISIBLE || + attrCheck.getAttributeType() == LevelAttribute.IS_ALL || + attrCheck.getAttributeType() == LevelAttribute.IS_UNIQUE) { + Boolean expectedBool = attrCheck.getExpectedBoolean(); + Boolean actualBool = getLevelBooleanAttribute(level, attrCheck.getAttributeType()); + matches = AttributeCheckHelper.compareBooleans(expectedBool, actualBool); + } else if (attrCheck.getAttributeType() == LevelAttribute.DEPTH || + attrCheck.getAttributeType() == LevelAttribute.ORDINAL || + attrCheck.getAttributeType() == LevelAttribute.CARDINALITY || + attrCheck.getAttributeType() == LevelAttribute.MEMBERS_WITH_DATA) { + Integer expectedInt = attrCheck.getExpectedInt(); + Integer actualInt = getLevelIntAttribute(level, attrCheck.getAttributeType()); + matches = AttributeCheckHelper.compareInts(expectedInt, actualInt); + } else { + matches = AttributeCheckHelper.compareValues( + attrCheck.getExpectedValue(), + actualValue, + attrCheck.getMatchMode(), + attrCheck.isCaseSensitive() + ); + } + + result.setStatus(matches ? CheckStatus.SUCCESS : CheckStatus.FAILURE); + return result; + } + + private String getLevelAttributeValue(Level level, LevelAttribute attributeType) { + return switch (attributeType) { + case NAME -> level.getName(); + case UNIQUE_NAME -> level.getUniqueName(); + case CAPTION -> level.getCaption(); + case DESCRIPTION -> level.getDescription(); + case VISIBLE -> String.valueOf(level.isVisible()); + case DEPTH -> String.valueOf(level.getDepth()); + case LEVEL_TYPE -> level.getLevelType() != null ? level.getLevelType().name() : null; + case IS_ALL -> String.valueOf(level.isAll()); + case IS_UNIQUE -> String.valueOf(level.isUnique()); + case ORDINAL -> String.valueOf(level.getDepth()); + case CARDINALITY -> String.valueOf(cube.getLevelCardinality(level, true, true)); + case MEMBERS_WITH_DATA -> "0"; + }; + } + + private Boolean getLevelBooleanAttribute(Level level, LevelAttribute attributeType) { + return switch (attributeType) { + case VISIBLE -> level.isVisible(); + case IS_ALL -> level.isAll(); + case IS_UNIQUE -> level.isUnique(); + default -> null; + }; + } + + private Integer getLevelIntAttribute(Level level, LevelAttribute attributeType) { + return switch (attributeType) { + case DEPTH -> level.getDepth(); + case ORDINAL -> level.getDepth(); + case CARDINALITY -> cube.getLevelCardinality(level, true, true); + case MEMBERS_WITH_DATA -> 0; + default -> null; + }; + } +} diff --git a/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/MeasureCheckExecutor.java b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/MeasureCheckExecutor.java new file mode 100644 index 0000000..3150b79 --- /dev/null +++ b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/MeasureCheckExecutor.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.runtime.impl.executors; + +import java.util.Date; +import java.util.List; +import java.util.Optional; + +import org.eclipse.daanse.olap.api.CatalogReader; +import org.eclipse.daanse.olap.api.connection.Connection; +import org.eclipse.daanse.olap.api.element.Cube; +import org.eclipse.daanse.olap.api.element.Member; +import org.eclipse.daanse.olap.check.model.check.AttributeCheckResult; +import org.eclipse.daanse.olap.check.model.check.CheckStatus; +import org.eclipse.daanse.olap.check.model.check.MeasureAttribute; +import org.eclipse.daanse.olap.check.model.check.MeasureAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.MeasureCheck; +import org.eclipse.daanse.olap.check.model.check.MeasureCheckResult; +import org.eclipse.daanse.olap.check.model.check.OlapCheckFactory; + +/** + * Executor for MeasureCheck that verifies measure existence and attributes. + */ +public class MeasureCheckExecutor { + + private final MeasureCheck check; + private final List measures; + private final Cube cube; + private final CatalogReader catalogReader; + private final Connection connection; + private final OlapCheckFactory factory; + + public MeasureCheckExecutor(MeasureCheck check, List measures, Cube cube, + CatalogReader catalogReader, Connection connection, OlapCheckFactory factory) { + this.check = check; + this.measures = measures; + this.cube = cube; + this.catalogReader = catalogReader; + this.connection = connection; + this.factory = factory; + } + + public MeasureCheckResult execute() { + long startTime = System.currentTimeMillis(); + Date start = new Date(); + + MeasureCheckResult result = factory.createMeasureCheckResult(); + result.setCheckName(check.getName()); + result.setCheckDescription(check.getDescription()); + result.setMeasureName(check.getMeasureName()); + result.setStartTime(start); + result.setSourceCheck(check); + + try { + // Find the measure + Optional foundMeasure = findMeasure(); + + if (foundMeasure.isEmpty()) { + result.setStatus(CheckStatus.FAILURE); + result.setEndTime(new Date()); + result.setExecutionTimeMs(System.currentTimeMillis() - startTime); + return result; + } + + Member measure = foundMeasure.get(); + result.setMeasureUniqueName(measure.getUniqueName()); + result.setStatus(CheckStatus.SUCCESS); + + // Execute attribute checks + for (MeasureAttributeCheck attrCheck : check.getMeasureAttributeChecks()) { + AttributeCheckResult attrResult = executeAttributeCheck(attrCheck, measure); + result.getAttributeResults().add(attrResult); + if (attrResult.getStatus() == CheckStatus.FAILURE) { + result.setStatus(CheckStatus.FAILURE); + } + } + + } catch (Exception e) { + result.setStatus(CheckStatus.FAILURE); + } + + result.setEndTime(new Date()); + result.setExecutionTimeMs(System.currentTimeMillis() - startTime); + + return result; + } + + private Optional findMeasure() { + String measureName = check.getMeasureName(); + String measureUniqueName = check.getMeasureUniqueName(); + + return measures.stream() + .filter(m -> { + if (measureUniqueName != null && !measureUniqueName.isEmpty()) { + return measureUniqueName.equals(m.getUniqueName()); + } + return measureName != null && measureName.equals(m.getName()); + }) + .findFirst(); + } + + private AttributeCheckResult executeAttributeCheck(MeasureAttributeCheck attrCheck, Member measure) { + AttributeCheckResult result = factory.createAttributeCheckResult(); + result.setCheckName(attrCheck.getName()); + result.setAttributeName(attrCheck.getAttributeType().getName()); + result.setExpectedValue(attrCheck.getExpectedValue()); + + String actualValue = getMeasureAttributeValue(measure, attrCheck.getAttributeType()); + result.setActualValue(actualValue); + + boolean matches; + if (attrCheck.getAttributeType() == MeasureAttribute.VISIBLE) { + Boolean expectedBool = attrCheck.getExpectedBoolean(); + Boolean actualBool = measure.isVisible(); + matches = AttributeCheckHelper.compareBooleans(expectedBool, actualBool); + } else { + matches = AttributeCheckHelper.compareValues( + attrCheck.getExpectedValue(), + actualValue, + attrCheck.getMatchMode(), + attrCheck.isCaseSensitive() + ); + } + + result.setStatus(matches ? CheckStatus.SUCCESS : CheckStatus.FAILURE); + return result; + } + + private String getMeasureAttributeValue(Member measure, MeasureAttribute attributeType) { + return switch (attributeType) { + case NAME -> measure.getName(); + case UNIQUE_NAME -> measure.getUniqueName(); + case CAPTION -> measure.getCaption(); + case DESCRIPTION -> measure.getDescription(); + case VISIBLE -> String.valueOf(measure.isVisible()); + case AGGREGATOR -> getPropertyString(measure, "AGGREGATOR"); + case DATA_TYPE -> getPropertyString(measure, "DATA_TYPE"); + case EXPRESSION -> getPropertyString(measure, "EXPRESSION"); + case FORMAT_STRING -> getPropertyString(measure, "FORMAT_STRING"); + case MEASURE_GROUP_NAME -> getPropertyString(measure, "MEASUREGROUP_NAME"); + }; + } + + private String getPropertyString(Member member, String propertyName) { + Object value = member.getPropertyValue(propertyName); + return value != null ? value.toString() : null; + } +} diff --git a/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/MemberCheckExecutor.java b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/MemberCheckExecutor.java new file mode 100644 index 0000000..99e0972 --- /dev/null +++ b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/MemberCheckExecutor.java @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.runtime.impl.executors; + +import java.util.Date; +import java.util.List; +import java.util.Optional; + +import org.eclipse.daanse.olap.api.CatalogReader; +import org.eclipse.daanse.olap.api.connection.Connection; +import org.eclipse.daanse.olap.api.element.Cube; +import org.eclipse.daanse.olap.api.element.Member; +import org.eclipse.daanse.olap.check.model.check.AttributeCheckResult; +import org.eclipse.daanse.olap.check.model.check.CheckStatus; +import org.eclipse.daanse.olap.check.model.check.MemberAttribute; +import org.eclipse.daanse.olap.check.model.check.MemberAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.MemberCheck; +import org.eclipse.daanse.olap.check.model.check.MemberCheckResult; +import org.eclipse.daanse.olap.check.model.check.OlapCheckFactory; +import org.eclipse.daanse.olap.check.model.check.PropertyCheck; +import org.eclipse.daanse.olap.check.model.check.PropertyCheckResult; + +/** + * Executor for MemberCheck that verifies member existence and properties. + */ +public class MemberCheckExecutor { + + private final MemberCheck check; + private final List members; + private final Cube cube; + private final CatalogReader catalogReader; + private final Connection connection; + private final OlapCheckFactory factory; + + public MemberCheckExecutor(MemberCheck check, List members, Cube cube, + CatalogReader catalogReader, Connection connection, OlapCheckFactory factory) { + this.check = check; + this.members = members; + this.cube = cube; + this.catalogReader = catalogReader; + this.connection = connection; + this.factory = factory; + } + + public MemberCheckResult execute() { + long startTime = System.currentTimeMillis(); + Date start = new Date(); + + MemberCheckResult result = factory.createMemberCheckResult(); + result.setCheckName(check.getName()); + result.setCheckDescription(check.getDescription()); + result.setMemberName(check.getMemberName()); + result.setStartTime(start); + result.setSourceCheck(check); + + try { + // Find the member + Optional foundMember = findMember(); + + if (foundMember.isEmpty()) { + result.setStatus(CheckStatus.FAILURE); + result.setEndTime(new Date()); + result.setExecutionTimeMs(System.currentTimeMillis() - startTime); + return result; + } + + Member member = foundMember.get(); + result.setMemberUniqueName(member.getUniqueName()); + result.setStatus(CheckStatus.SUCCESS); + + // Execute attribute checks + for (MemberAttributeCheck attrCheck : check.getMemberAttributeChecks()) { + AttributeCheckResult attrResult = executeAttributeCheck(attrCheck, member); + result.getAttributeResults().add(attrResult); + if (attrResult.getStatus() == CheckStatus.FAILURE) { + result.setStatus(CheckStatus.FAILURE); + } + } + + // Execute property checks + for (PropertyCheck propertyCheck : check.getPropertyChecks()) { + if (!propertyCheck.isEnabled()) { + continue; + } + + PropertyCheckResult propResult = executePropertyCheck(propertyCheck, member); + result.getPropertyResults().add(propResult); + + if (propResult.getStatus() == CheckStatus.FAILURE) { + result.setStatus(CheckStatus.FAILURE); + } + } + + } catch (Exception e) { + result.setStatus(CheckStatus.FAILURE); + } + + result.setEndTime(new Date()); + result.setExecutionTimeMs(System.currentTimeMillis() - startTime); + + return result; + } + + private Optional findMember() { + String memberName = check.getMemberName(); + String memberUniqueName = check.getMemberUniqueName(); + + return members.stream() + .filter(m -> { + if (memberUniqueName != null && !memberUniqueName.isEmpty()) { + return memberUniqueName.equals(m.getUniqueName()); + } + return memberName != null && memberName.equals(m.getName()); + }) + .findFirst(); + } + + private AttributeCheckResult executeAttributeCheck(MemberAttributeCheck attrCheck, Member member) { + AttributeCheckResult result = factory.createAttributeCheckResult(); + result.setCheckName(attrCheck.getName()); + result.setAttributeName(attrCheck.getAttributeType().getName()); + result.setExpectedValue(attrCheck.getExpectedValue()); + + String actualValue = getMemberAttributeValue(member, attrCheck.getAttributeType()); + result.setActualValue(actualValue); + + boolean matches; + if (attrCheck.getAttributeType() == MemberAttribute.VISIBLE || + attrCheck.getAttributeType() == MemberAttribute.IS_CALCULATED || + attrCheck.getAttributeType() == MemberAttribute.IS_DATA_MEMBER) { + Boolean expectedBool = attrCheck.getExpectedBoolean(); + Boolean actualBool = getMemberBooleanAttribute(member, attrCheck.getAttributeType()); + matches = AttributeCheckHelper.compareBooleans(expectedBool, actualBool); + } else if (attrCheck.getAttributeType() == MemberAttribute.ORDINAL || + attrCheck.getAttributeType() == MemberAttribute.DEPTH || + attrCheck.getAttributeType() == MemberAttribute.PARENT_COUNT || + attrCheck.getAttributeType() == MemberAttribute.CHILDREN_CARDINALITY) { + Integer expectedInt = attrCheck.getExpectedInt(); + Integer actualInt = getMemberIntAttribute(member, attrCheck.getAttributeType()); + matches = AttributeCheckHelper.compareInts(expectedInt, actualInt); + } else { + matches = AttributeCheckHelper.compareValues( + attrCheck.getExpectedValue(), + actualValue, + attrCheck.getMatchMode(), + attrCheck.isCaseSensitive() + ); + } + + result.setStatus(matches ? CheckStatus.SUCCESS : CheckStatus.FAILURE); + return result; + } + + private String getMemberAttributeValue(Member member, MemberAttribute attributeType) { + return switch (attributeType) { + case NAME -> member.getName(); + case UNIQUE_NAME -> member.getUniqueName(); + case CAPTION -> member.getCaption(); + case DESCRIPTION -> member.getDescription(); + case VISIBLE -> String.valueOf(member.isVisible()); + case MEMBER_TYPE -> member.getMemberType() != null ? member.getMemberType().name() : null; + case IS_CALCULATED -> String.valueOf(member.isCalculated()); + case IS_DATA_MEMBER -> String.valueOf(member.getDataMember() != null && member.getDataMember() != member); + case PARENT_UNIQUE_NAME -> { + Member parent = member.getParentMember(); + yield parent != null ? parent.getUniqueName() : null; + } + case PARENT_COUNT -> "1"; // Typically 1 for non-ragged hierarchies + case CHILDREN_CARDINALITY -> "0"; // Would need to calculate + case ORDINAL -> String.valueOf(member.getOrdinal()); + case DEPTH -> String.valueOf(member.getDepth()); + }; + } + + private Boolean getMemberBooleanAttribute(Member member, MemberAttribute attributeType) { + return switch (attributeType) { + case VISIBLE -> member.isVisible(); + case IS_CALCULATED -> member.isCalculated(); + case IS_DATA_MEMBER -> member.getDataMember() != null && member.getDataMember() != member; + default -> null; + }; + } + + private Integer getMemberIntAttribute(Member member, MemberAttribute attributeType) { + return switch (attributeType) { + case ORDINAL -> member.getOrdinal(); + case DEPTH -> member.getDepth(); + case PARENT_COUNT -> 1; + case CHILDREN_CARDINALITY -> 0; + default -> null; + }; + } + + private PropertyCheckResult executePropertyCheck(PropertyCheck propertyCheck, Member member) { + long startTime = System.currentTimeMillis(); + Date start = new Date(); + + PropertyCheckResult result = factory.createPropertyCheckResult(); + result.setCheckName(propertyCheck.getName()); + result.setCheckDescription(propertyCheck.getDescription()); + result.setPropertyName(propertyCheck.getPropertyName()); + result.setStartTime(start); + result.setSourceCheck(propertyCheck); + + try { + // Get property value from member + Object actualValueObj = member.getPropertyValue(propertyCheck.getPropertyName()); + String actualValue = actualValueObj != null ? actualValueObj.toString() : null; + result.setActualValue(actualValue); + + // Compare with expected value + String expectedValue = propertyCheck.getExpectedValue(); + result.setExpectedValue(expectedValue); + + boolean matches = AttributeCheckHelper.compareValues( + expectedValue, + actualValue, + propertyCheck.getMatchMode(), + propertyCheck.isCaseSensitive() + ); + result.setStatus(matches ? CheckStatus.SUCCESS : CheckStatus.FAILURE); + + } catch (Exception e) { + result.setStatus(CheckStatus.FAILURE); + } + + result.setEndTime(new Date()); + result.setExecutionTimeMs(System.currentTimeMillis() - startTime); + + return result; + } +} diff --git a/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/NamedSetCheckExecutor.java b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/NamedSetCheckExecutor.java new file mode 100644 index 0000000..5356c6e --- /dev/null +++ b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/NamedSetCheckExecutor.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.runtime.impl.executors; + +import java.util.Date; +import java.util.List; +import java.util.Optional; + +import org.eclipse.daanse.olap.api.element.NamedSet; +import org.eclipse.daanse.olap.check.model.check.AttributeCheckResult; +import org.eclipse.daanse.olap.check.model.check.CheckStatus; +import org.eclipse.daanse.olap.check.model.check.NamedSetAttribute; +import org.eclipse.daanse.olap.check.model.check.NamedSetAttributeCheck; +import org.eclipse.daanse.olap.check.model.check.NamedSetCheck; +import org.eclipse.daanse.olap.check.model.check.NamedSetCheckResult; +import org.eclipse.daanse.olap.check.model.check.OlapCheckFactory; + +/** + * Executor for NamedSetCheck that verifies named set existence and attributes. + */ +public class NamedSetCheckExecutor { + + private final NamedSetCheck check; + private final List namedSets; + private final OlapCheckFactory factory; + + public NamedSetCheckExecutor(NamedSetCheck check, List namedSets, OlapCheckFactory factory) { + this.check = check; + this.namedSets = namedSets; + this.factory = factory; + } + + public NamedSetCheckResult execute() { + long startTime = System.currentTimeMillis(); + Date start = new Date(); + + NamedSetCheckResult result = factory.createNamedSetCheckResult(); + result.setCheckName(check.getName()); + result.setCheckDescription(check.getDescription()); + result.setNamedSetName(check.getNamedSetName()); + result.setStartTime(start); + result.setSourceCheck(check); + + try { + // Find the NamedSet + Optional foundNamedSet = findNamedSet(); + + if (foundNamedSet.isEmpty()) { + result.setStatus(CheckStatus.FAILURE); + result.setEndTime(new Date()); + result.setExecutionTimeMs(System.currentTimeMillis() - startTime); + return result; + } + + NamedSet namedSet = foundNamedSet.get(); + result.setStatus(CheckStatus.SUCCESS); + + // Execute attribute checks + for (NamedSetAttributeCheck attrCheck : check.getNamedSetAttributeChecks()) { + AttributeCheckResult attrResult = executeAttributeCheck(attrCheck, namedSet); + result.getAttributeResults().add(attrResult); + if (attrResult.getStatus() == CheckStatus.FAILURE) { + result.setStatus(CheckStatus.FAILURE); + } + } + + } catch (Exception e) { + result.setStatus(CheckStatus.FAILURE); + } + + result.setEndTime(new Date()); + result.setExecutionTimeMs(System.currentTimeMillis() - startTime); + + return result; + } + + private Optional findNamedSet() { + String namedSetName = check.getNamedSetName(); + + return namedSets.stream() + .filter(ns -> namedSetName != null && namedSetName.equals(ns.getName())) + .findFirst(); + } + + private AttributeCheckResult executeAttributeCheck(NamedSetAttributeCheck attrCheck, NamedSet namedSet) { + AttributeCheckResult result = factory.createAttributeCheckResult(); + result.setCheckName(attrCheck.getName()); + result.setAttributeName(attrCheck.getAttributeType().getName()); + result.setExpectedValue(attrCheck.getExpectedValue()); + + String actualValue = getNamedSetAttributeValue(namedSet, attrCheck.getAttributeType()); + result.setActualValue(actualValue); + + boolean matches; + if (attrCheck.getAttributeType() == NamedSetAttribute.IS_DYNAMIC) { + Boolean expectedBool = attrCheck.getExpectedBoolean(); + Boolean actualBool = namedSet.isDynamic(); + matches = AttributeCheckHelper.compareBooleans(expectedBool, actualBool); + } else { + matches = AttributeCheckHelper.compareValues( + attrCheck.getExpectedValue(), + actualValue, + attrCheck.getMatchMode(), + attrCheck.isCaseSensitive() + ); + } + + result.setStatus(matches ? CheckStatus.SUCCESS : CheckStatus.FAILURE); + return result; + } + + private String getNamedSetAttributeValue(NamedSet namedSet, NamedSetAttribute attributeType) { + return switch (attributeType) { + case NAME -> namedSet.getName(); + case CAPTION -> namedSet.getCaption(); + case DESCRIPTION -> namedSet.getDescription(); + case DISPLAY_FOLDER -> namedSet.getDisplayFolder(); + case IS_DYNAMIC -> String.valueOf(namedSet.isDynamic()); + case EXPRESSION -> namedSet.getExp() != null ? namedSet.getExp().toString() : null; + }; + } +} diff --git a/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/QueryCheckExecutor.java b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/QueryCheckExecutor.java new file mode 100644 index 0000000..2a55a95 --- /dev/null +++ b/check/runtime/src/main/java/org/eclipse/daanse/olap/check/runtime/impl/executors/QueryCheckExecutor.java @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.daanse.olap.check.runtime.impl.executors; + +import java.util.Date; + +import org.eclipse.daanse.olap.api.connection.Connection; +import org.eclipse.daanse.olap.api.result.Axis; +import org.eclipse.daanse.olap.api.result.Cell; +import org.eclipse.daanse.olap.api.result.Result; +import org.eclipse.daanse.olap.check.model.check.CellCheckResult; +import org.eclipse.daanse.olap.check.model.check.CellValueCheck; +import org.eclipse.daanse.olap.check.model.check.CheckStatus; +import org.eclipse.daanse.olap.check.model.check.OlapCheckFactory; +import org.eclipse.daanse.olap.check.model.check.QueryCheck; +import org.eclipse.daanse.olap.check.model.check.QueryCheckResult; +import org.eclipse.daanse.olap.check.model.check.QueryLanguage; +import org.eclipse.emf.common.util.EList; + +/** + * Executor for QueryCheck that verifies query execution and results. + * Supports MDX, SQL, and DAX query languages. + */ +public class QueryCheckExecutor { + + private final QueryCheck check; + private final Connection connection; + private final OlapCheckFactory factory; + + public QueryCheckExecutor(QueryCheck check, Connection connection, OlapCheckFactory factory) { + this.check = check; + this.connection = connection; + this.factory = factory; + } + + public QueryCheckResult execute() { + long startTime = System.currentTimeMillis(); + Date start = new Date(); + + QueryCheckResult result = factory.createQueryCheckResult(); + result.setCheckName(check.getName()); + result.setCheckDescription(check.getDescription()); + result.setQuery(check.getQuery()); + result.setQueryLanguage(check.getQueryLanguage()); + result.setStartTime(start); + result.setSourceCheck(check); + + try { + QueryLanguage language = check.getQueryLanguage(); + if (language == null) { + language = QueryLanguage.MDX; // Default to MDX + } + + switch (language) { + case MDX: + executeMdxQuery(result, startTime); + break; + case SQL: + executeSqlQuery(result, startTime); + break; + case DAX: + executeDaxQuery(result, startTime); + break; + default: + result.setExecutedSuccessfully(false); + result.setStatus(CheckStatus.FAILURE); + } + + } catch (Exception e) { + result.setExecutedSuccessfully(false); + result.setStatus(CheckStatus.FAILURE); + } + + result.setEndTime(new Date()); + result.setExecutionTimeMs(System.currentTimeMillis() - startTime); + + return result; + } + + private void executeMdxQuery(QueryCheckResult result, long startTime) { + try { + // Execute the MDX query + Result mdxResult = connection.execute( + connection.parseQuery(check.getQuery()) + ); + + result.setExecutedSuccessfully(true); + + // Get axes for counting rows/columns + Axis[] axes = mdxResult.getAxes(); + int rowCount = 0; + int columnCount = 0; + + if (axes.length > 0) { + columnCount = axes[0].getPositions().size(); + } + if (axes.length > 1) { + rowCount = axes[1].getPositions().size(); + } + + result.setRowCount(rowCount); + result.setColumnCount(columnCount); + result.setStatus(CheckStatus.SUCCESS); + + // Check expected row count (-1 means not specified) + int expectedRowCount = check.getExpectedRowCount(); + if (expectedRowCount >= 0 && rowCount != expectedRowCount) { + result.setStatus(CheckStatus.FAILURE); + } + + // Check expected column count (-1 means not specified) + int expectedColumnCount = check.getExpectedColumnCount(); + if (expectedColumnCount >= 0 && columnCount != expectedColumnCount) { + result.setStatus(CheckStatus.FAILURE); + } + + // Check execution time (-1 means not specified) + long executionTime = System.currentTimeMillis() - startTime; + long maxExecutionTime = check.getMaxExecutionTimeMs(); + if (maxExecutionTime > 0 && executionTime > maxExecutionTime) { + result.setStatus(CheckStatus.FAILURE); + } + + // Execute cell value checks + for (CellValueCheck cellCheck : check.getCellChecks()) { + CellCheckResult cellResult = executeCellCheck(cellCheck, mdxResult); + result.getCellResults().add(cellResult); + if (cellResult.getStatus() == CheckStatus.FAILURE) { + result.setStatus(CheckStatus.FAILURE); + } + } + + } catch (Exception e) { + result.setExecutedSuccessfully(false); + result.setStatus(CheckStatus.FAILURE); + } + } + + private void executeSqlQuery(QueryCheckResult result, long startTime) { + // TODO: Implement SQL query execution + // SQL queries would typically use JDBC to execute against the underlying database + result.setExecutedSuccessfully(false); + result.setStatus(CheckStatus.FAILURE); + } + + private void executeDaxQuery(QueryCheckResult result, long startTime) { + // TODO: Implement DAX query execution + // DAX queries would need to use appropriate DAX execution mechanism + result.setExecutedSuccessfully(false); + result.setStatus(CheckStatus.FAILURE); + } + + private CellCheckResult executeCellCheck(CellValueCheck cellCheck, Result mdxResult) { + CellCheckResult result = factory.createCellCheckResult(); + result.setCheckName(cellCheck.getName()); + + // Copy coordinates + EList coords = cellCheck.getCoordinates(); + result.getCoordinates().addAll(coords); + result.setExpectedValue(cellCheck.getExpectedValue()); + + try { + // Convert EList to int[] + int[] coordArray = new int[coords.size()]; + for (int i = 0; i < coords.size(); i++) { + coordArray[i] = coords.get(i); + } + + Cell cell = mdxResult.getCell(coordArray); + + Object cellValue = cell.getValue(); + String actualValue = cellValue != null ? cellValue.toString() : null; + + if (cellCheck.isCheckFormattedValue()) { + actualValue = cell.getFormattedValue(); + } + + result.setActualValue(actualValue); + + // Compare values + boolean matches; + double expectedNumeric = cellCheck.getExpectedNumericValue(); + + // Check if numeric comparison is needed (non-zero expectedNumericValue indicates it's set) + if (expectedNumeric != 0.0 || cellCheck.getExpectedValue() == null) { + // Numeric comparison with tolerance + Double actual = cellValue instanceof Number ? ((Number) cellValue).doubleValue() : null; + double tolerance = cellCheck.getTolerance(); + + matches = actual != null && Math.abs(expectedNumeric - actual) <= tolerance; + } else { + // String comparison + matches = AttributeCheckHelper.compareValues( + cellCheck.getExpectedValue(), + actualValue, + cellCheck.getMatchMode(), + true // cell values are case-sensitive by default + ); + } + + result.setStatus(matches ? CheckStatus.SUCCESS : CheckStatus.FAILURE); + + } catch (Exception e) { + result.setStatus(CheckStatus.FAILURE); + } + + return result; + } +} diff --git a/pom.xml b/pom.xml index cccc029..15e45ae 100644 --- a/pom.xml +++ b/pom.xml @@ -59,6 +59,7 @@ spi format odc + check