diff --git a/pom.xml b/pom.xml
index d95a761b..ce2ac285 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,13 +6,13 @@
org.springframework.bootspring-boot-starter-parent
- 2.7.18
+ 3.2.10com.activeviam.toolsmac
- 3.0.0-SNAPSHOT
+ 3.1.0-SNAPSHOTAtoti Server Memory Analysis Cube
@@ -23,12 +23,11 @@
- 11
+ 21
- 6.0.10
- 5.1.13
+ 6.1.3-1733969770-ef208661
- 9.0.31
+ 10.1.30com.activeviam.mac.app.MacSpringBootApp
@@ -46,49 +45,41 @@
pomimport
+
+ jakarta.servlet
+ jakarta.servlet-api
+ 6.0.0
+
+
+ org.springframework.boot
+ spring-boot-starter-json
+ 3.2.10
+
- org.projectlombok
- lombok
- provided
-
-
-
-
- com.activeviam.activepivot
- activepivot-server-spring
-
-
-
-
-
- com.activeviam.tech
- composer-intf
- compile
-
-
- com.activeviam.tech
- composer-impl
- compile
+ com.activeviam.springboot
+ atoti-server-starter
+ ${atoti-server.version}
-
- com.activeviam.tech
- content-server-spring
+ com.activeviam.springboot
+ atoti-ui-starter
+ ${atoti-server.version}
- com.activeviam.web
- activeviam-web-spring
+ org.projectlombok
+ lombok
+ providedorg.hibernatehibernate-core
+ 6.4.10.Finalcom.h2database
@@ -97,14 +88,7 @@
org.hibernatehibernate-c3p0
-
-
-
-
- com.activeviam.activeui
- activeui
- ${atoti-ui.version}
- runtime
+ 6.4.10.Final
@@ -149,11 +133,6 @@
mockito-coretest
-
- javax.servlet
- javax.servlet-api
- provided
- junitjunit
@@ -170,6 +149,45 @@
32.1.3-jretest
+
+ com.activeviam.source
+ csv-source
+ ${atoti-server.version}
+
+
+ org.apache.commons
+ commons-compress
+ 1.27.1
+
+
+ jakarta.persistence
+ jakarta.persistence-api
+ ${jakarta-persistence.version}
+
+
+ org.yaml
+ snakeyaml
+ 2.2
+
+
+ jakarta.ws.rs
+ jakarta.ws.rs-api
+ ${jakarta-ws-rs.version}
+
+
+ org.springframework
+ spring-web
+ ${spring-framework.version}
+
+
+ org.apache.tomcat.embed
+ tomcat-embed-core
+ ${tomcat.version}
+
+
+ org.springframework.boot
+ spring-boot-autoconfigure
+
diff --git a/src/main/java/com/activeviam/mac/app/MacSpringBootApp.java b/src/main/java/com/activeviam/mac/app/MacSpringBootApp.java
index c544cf8a..95c2c7f3 100644
--- a/src/main/java/com/activeviam/mac/app/MacSpringBootApp.java
+++ b/src/main/java/com/activeviam/mac/app/MacSpringBootApp.java
@@ -8,9 +8,7 @@
package com.activeviam.mac.app;
import com.activeviam.mac.cfg.impl.MacServerConfig;
-import com.quartetfs.fwk.Registry;
-import com.quartetfs.fwk.contributions.impl.ClasspathContributionProvider;
-import javax.servlet.MultipartConfigElement;
+import jakarta.servlet.MultipartConfigElement;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
@@ -36,11 +34,6 @@
@Import({MacServerConfig.class})
public class MacSpringBootApp {
- /* Before anything else we statically initialize the Quartet FS Registry. */
- static {
- Registry.setContributionProvider(new ClasspathContributionProvider());
- }
-
/**
* Starts the Memory Analysis Cube application.
*
diff --git a/src/main/java/com/activeviam/mac/cfg/impl/ActivePivotWithDatastoreConfig.java b/src/main/java/com/activeviam/mac/cfg/impl/ActivePivotWithDatastoreConfig.java
new file mode 100644
index 00000000..2c2b51df
--- /dev/null
+++ b/src/main/java/com/activeviam/mac/cfg/impl/ActivePivotWithDatastoreConfig.java
@@ -0,0 +1,48 @@
+package com.activeviam.mac.cfg.impl;
+
+import com.activeviam.activepivot.core.datastore.api.builder.ApplicationWithDatastore;
+import com.activeviam.activepivot.core.datastore.api.builder.StartBuilding;
+import com.activeviam.activepivot.core.intf.api.cube.IActivePivotManager;
+import com.activeviam.activepivot.server.spring.api.config.IActivePivotBranchPermissionsManagerConfig;
+import com.activeviam.activepivot.server.spring.api.config.IActivePivotConfig;
+import com.activeviam.activepivot.server.spring.api.config.IActivePivotManagerDescriptionConfig;
+import com.activeviam.activepivot.server.spring.api.config.IDatastoreConfig;
+import com.activeviam.activepivot.server.spring.api.config.IDatastoreSchemaDescriptionConfig;
+import com.activeviam.database.datastore.api.IDatastore;
+import lombok.RequiredArgsConstructor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@RequiredArgsConstructor
+public class ActivePivotWithDatastoreConfig implements IDatastoreConfig, IActivePivotConfig {
+
+ private final IActivePivotManagerDescriptionConfig apManagerConfig;
+
+ private final IDatastoreSchemaDescriptionConfig datastoreDescriptionConfig;
+
+ private final IActivePivotBranchPermissionsManagerConfig branchPermissionsManagerConfig;
+
+ @Bean
+ protected ApplicationWithDatastore applicationWithDatastore() {
+ return StartBuilding.application()
+ .withDatastore(this.datastoreDescriptionConfig.datastoreSchemaDescription())
+ .withManager(this.apManagerConfig.managerDescription())
+ .withEpochPolicy(this.apManagerConfig.epochManagementPolicy())
+ .withBranchPermissionsManager(
+ this.branchPermissionsManagerConfig.branchPermissionsManager())
+ .build();
+ }
+
+ @Bean
+ @Override
+ public IActivePivotManager activePivotManager() {
+ return applicationWithDatastore().getManager();
+ }
+
+ @Bean
+ @Override
+ public IDatastore database() {
+ return applicationWithDatastore().getDatastore();
+ }
+}
diff --git a/src/main/java/com/activeviam/mac/cfg/impl/ActiveUiResourceServerConfig.java b/src/main/java/com/activeviam/mac/cfg/impl/ActiveUiResourceServerConfig.java
deleted file mode 100644
index dc965ed7..00000000
--- a/src/main/java/com/activeviam/mac/cfg/impl/ActiveUiResourceServerConfig.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * (C) ActiveViam 2016
- * ALL RIGHTS RESERVED. This material is the CONFIDENTIAL and PROPRIETARY
- * property of ActiveViam. Any unauthorized use,
- * reproduction or transfer of this material is strictly prohibited
- */
-
-package com.activeviam.mac.cfg.impl;
-
-import com.qfs.server.cfg.impl.ASpringResourceServerConfig;
-import java.util.Collections;
-import java.util.Set;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * Spring configuration for Atoti UI web application.
- *
- * @author ActiveViam
- */
-@Configuration
-public class ActiveUiResourceServerConfig extends ASpringResourceServerConfig {
-
- /** The namespace of the Atoti UI web application. */
- public static final String NAMESPACE = "ui";
-
- /** Constructor. */
- public ActiveUiResourceServerConfig() {
- super("/" + NAMESPACE);
- }
-
- @Override
- protected void registerRedirections(final ResourceRegistry registry) {
- super.registerRedirections(registry);
- // Redirect from the root to ActiveUI
- registry.redirectTo(NAMESPACE + "/index.html", "/");
- // Redirect the calls to env*.js to the AP ones rather than the default of the ActiveUI apps
- registry.serve("/content/ui/env*.js").addResourceLocations("classpath:/static/content/");
- registry.serve("/ui/env*.js").addResourceLocations("classpath:/static/activeui/");
- registerExtensions(registry);
- }
-
- protected void registerExtensions(final ResourceRegistry registry) {
- registry.serve("/ui/extensions*.json").addResourceLocations("classpath:/static/activeui/");
- registry
- .serve("/ui/extensions/text-editor-extension/**/*.js")
- .addResourceLocations("classpath:/static/activeui/extensions/text-editor-extension/");
- }
-
- /**
- * Registers resources to serve.
- *
- * @param registry registry to use
- */
- @Override
- protected void registerResources(final ResourceRegistry registry) {
- super.registerResources(registry);
-
- // ActiveUI web app also serves request to the root, so that the redirection from root to
- // ActiveUI works
- registry
- .serve("/")
- .addResourceLocations("/", "classpath:META-INF/resources/")
- .setCacheControl(getDefaultCacheControl());
- }
-
- /**
- * Gets the extensions of files to serve.
- *
- * @return all files extensions
- */
- @Override
- public Set getServedExtensions() {
- return Set.of(
- // Default HTML files
- "html",
- "js",
- "css",
- "map",
- "json",
- // Image extensions
- "png",
- "jpg",
- "gif",
- "ico",
- // Font extensions
- "eot",
- "svg",
- "ttf",
- "woff",
- "woff2");
- }
-
- @Override
- public Set getServedDirectories() {
- return Collections.singleton("/");
- }
-
- @Override
- public Set getResourceLocations() {
- // ActiveUI is integrated in the sandbox project thanks to Maven integration.
- // You can read more about this feature here
- // https://support.activeviam.com/documentation/activeui/4.2.0/dev/setup/maven-integration.html
-
- return Set.of(
- "/activeui/", // index.html, favicon.ico, etc.
- "classpath:META-INF/resources/webjars/activeui/"); // ActiveUI SDK UMD scripts
- // and supporting assets
- }
-}
diff --git a/src/main/java/com/activeviam/mac/cfg/impl/ContentServiceConfig.java b/src/main/java/com/activeviam/mac/cfg/impl/ContentServiceConfig.java
index 39fa04a5..7025e4a1 100644
--- a/src/main/java/com/activeviam/mac/cfg/impl/ContentServiceConfig.java
+++ b/src/main/java/com/activeviam/mac/cfg/impl/ContentServiceConfig.java
@@ -7,33 +7,39 @@
package com.activeviam.mac.cfg.impl;
+import static com.activeviam.tech.contentserver.storage.api.ContentServiceSnapshotter.create;
+
+import com.activeviam.activepivot.core.intf.api.contextvalues.IContextValue;
+import com.activeviam.activepivot.core.intf.api.description.ICalculatedMemberDescription;
+import com.activeviam.activepivot.core.intf.api.description.IKpiDescription;
+import com.activeviam.activepivot.server.intf.api.entitlements.IActivePivotContentService;
+import com.activeviam.activepivot.server.spring.api.config.IActivePivotContentServiceConfig;
+import com.activeviam.activepivot.server.spring.api.content.ActivePivotContentServiceBuilder;
import com.activeviam.mac.cfg.security.impl.SecurityConfig;
+import com.activeviam.tech.contentserver.spring.internal.config.ContentServerRestServicesConfig;
+import com.activeviam.tech.contentserver.storage.api.IContentService;
+import com.activeviam.tech.contentserver.storage.private_.HibernateContentService;
+import com.activeviam.tech.core.internal.monitoring.JmxOperation;
import com.activeviam.tools.bookmark.constant.impl.ContentServerConstants.Paths;
import com.activeviam.tools.bookmark.constant.impl.ContentServerConstants.Role;
import com.activeviam.tools.bookmark.impl.BookmarkTool;
-import com.qfs.content.cfg.impl.ContentServerRestServicesConfig;
-import com.qfs.content.service.IContentService;
-import com.qfs.content.service.impl.HibernateContentService;
-import com.qfs.content.snapshot.impl.ContentServiceSnapshotter;
-import com.qfs.jmx.JmxOperation;
-import com.qfs.pivot.content.IActivePivotContentService;
-import com.qfs.pivot.content.impl.ActivePivotContentServiceBuilder;
-import com.qfs.server.cfg.content.IActivePivotContentServiceConfig;
-import com.quartetfs.biz.pivot.context.IContextValue;
-import com.quartetfs.biz.pivot.definitions.ICalculatedMemberDescription;
-import com.quartetfs.biz.pivot.definitions.IKpiDescription;
+import java.io.IOException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.sql.DataSource;
+import lombok.RequiredArgsConstructor;
+import org.hibernate.HibernateException;
+import org.hibernate.SessionFactory;
import org.hibernate.cfg.AvailableSettings;
import org.springframework.beans.factory.BeanInitializationException;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
/**
* Spring configuration of the Content Service.
@@ -46,21 +52,9 @@
* @author ActiveViam
*/
@Configuration
+@RequiredArgsConstructor
public class ContentServiceConfig implements IActivePivotContentServiceConfig {
- /**
- * The name of the property which contains the role allowed to add new calculated members in the
- * configuration service.
- */
- public static final String CALCULATED_MEMBER_ROLE_PROPERTY =
- "contentServer.security.calculatedMemberRole";
-
- /**
- * The name of the property which contains the role allowed to add new KPIs in the configuration
- * service.
- */
- public static final String KPI_ROLE_PROPERTY = "contentServer.security.kpiRole";
-
/**
* The name of the property that controls whether or not to force the reloading of the predefined
* bookmarks even if they were already loaded previously.
@@ -70,19 +64,22 @@ public class ContentServiceConfig implements IActivePivotContentServiceConfig {
/** The name of the property that precise the name of the folder the bookmarks are in. */
public static final String UI_FOLDER_PROPERTY = "bookmarks.folder";
- /** Instance of the Spring context environment. */
- @Autowired public Environment env;
+ private final Environment env;
/**
* Loads the Hibernate's configuration from the specified file.
*
* @return the Hibernate's configuration
*/
- private static org.hibernate.cfg.Configuration loadConfiguration(
- final Properties hibernateProperties) {
+ private static SessionFactory loadConfiguration(final Properties hibernateProperties)
+ throws HibernateException, IOException {
hibernateProperties.put(
AvailableSettings.DATASOURCE, createTomcatJdbcDataSource(hibernateProperties));
- return new org.hibernate.cfg.Configuration().addProperties(hibernateProperties);
+ final Resource entityMappingFile = new ClassPathResource("content-service-hibernate.xml");
+ return new org.hibernate.cfg.Configuration()
+ .addProperties(hibernateProperties)
+ .addInputStream(entityMappingFile.getInputStream())
+ .buildSessionFactory();
}
/**
@@ -132,8 +129,17 @@ public Properties contentServiceHibernateProperties() {
@Override
@Bean
public IContentService contentService() {
- org.hibernate.cfg.Configuration conf = loadConfiguration(contentServiceHibernateProperties());
- return new HibernateContentService(conf);
+ if ("db".equals(this.env.getProperty("content-service.type", "db"))) {
+ return IContentService.builder().inMemory().build();
+ } else {
+ final SessionFactory sessionFactory;
+ try {
+ sessionFactory = loadConfiguration(contentServiceHibernateProperties());
+ return new HibernateContentService(sessionFactory);
+ } catch (HibernateException | IOException e) {
+ throw new BeanInitializationException("Failed to initialize the Content Service", e);
+ }
+ }
}
/**
@@ -149,18 +155,16 @@ public IActivePivotContentService activePivotContentService() {
return new ActivePivotContentServiceBuilder()
.with(contentService())
.withCacheForEntitlements(-1)
- .needInitialization(
- this.env.getRequiredProperty(CALCULATED_MEMBER_ROLE_PROPERTY),
- this.env.getRequiredProperty(KPI_ROLE_PROPERTY))
+ .needInitialization(SecurityConfig.ROLE_USER, SecurityConfig.ROLE_USER)
.build();
}
private Map> defaultBookmarkPermissions() {
return Map.of(
Role.OWNERS,
- List.of(SecurityConfig.ROLE_CS_ROOT),
+ List.of(SecurityConfig.ROLE_USER),
Role.READERS,
- List.of(SecurityConfig.ROLE_CS_ROOT));
+ List.of(SecurityConfig.ROLE_USER));
}
/**
@@ -173,16 +177,14 @@ private Map> defaultBookmarkPermissions() {
desc = "Export the current bookmark structure",
params = {"destination"})
public void exportBookMarks(String destination) {
- BookmarkTool.exportBookmarks(
- new ContentServiceSnapshotter(contentService().withRootPrivileges()), destination);
+ BookmarkTool.exportBookmarks(create(contentService().withRootPrivileges()), destination);
}
/** Loads the bookmarks packaged with the application. */
public void loadPredefinedBookmarks() {
final var service = contentService().withRootPrivileges();
if (!service.exists("/" + Paths.UI) || shouldReloadBookmarks()) {
- BookmarkTool.importBookmarks(
- new ContentServiceSnapshotter(service), defaultBookmarkPermissions());
+ BookmarkTool.importBookmarks(create(service), defaultBookmarkPermissions());
}
}
diff --git a/src/main/java/com/activeviam/mac/cfg/impl/MacServerConfig.java b/src/main/java/com/activeviam/mac/cfg/impl/MacServerConfig.java
index 93575e25..b7f81e14 100644
--- a/src/main/java/com/activeviam/mac/cfg/impl/MacServerConfig.java
+++ b/src/main/java/com/activeviam/mac/cfg/impl/MacServerConfig.java
@@ -7,27 +7,13 @@
package com.activeviam.mac.cfg.impl;
+import com.activeviam.activepivot.server.spring.api.config.IActivePivotConfig;
+import com.activeviam.activepivot.server.spring.api.config.IActivePivotContentServiceConfig;
+import com.activeviam.activepivot.server.spring.api.config.IDatastoreConfig;
import com.activeviam.mac.cfg.security.impl.SecurityConfig;
-import com.activeviam.mac.cfg.security.impl.UserConfig;
-import com.activeviam.properties.cfg.impl.ActiveViamPropertyFromSpringConfig;
-import com.qfs.pivot.content.impl.DynamicActivePivotContentServiceMBean;
-import com.qfs.pivot.monitoring.impl.MemoryAnalysisService;
-import com.qfs.server.cfg.IActivePivotConfig;
-import com.qfs.server.cfg.IDatastoreConfig;
-import com.qfs.server.cfg.content.IActivePivotContentServiceConfig;
-import com.qfs.server.cfg.i18n.impl.LocalI18nConfig;
-import com.qfs.server.cfg.impl.ActivePivotServicesConfig;
-import com.qfs.server.cfg.impl.ActivePivotWithDatastoreConfig;
-import com.qfs.server.cfg.impl.ActivePivotXmlaServletConfig;
-import com.qfs.server.cfg.impl.ActiveViamRestServicesConfig;
-import com.qfs.server.cfg.impl.ActiveViamWebSocketServicesConfig;
-import com.qfs.server.cfg.impl.FullAccessBranchPermissionsManagerConfig;
-import com.qfs.server.cfg.impl.JwtConfig;
-import com.qfs.server.cfg.impl.JwtRestServiceConfig;
-import com.quartetfs.biz.pivot.monitoring.impl.DynamicActivePivotManagerMBean;
-import com.quartetfs.fwk.AgentException;
-import com.quartetfs.fwk.monitoring.jmx.impl.JMXEnabler;
-import java.nio.file.Paths;
+import com.activeviam.tech.core.api.agent.AgentException;
+import com.activeviam.web.spring.internal.JMXEnabler;
+import com.activeviam.web.spring.internal.config.JwtConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.annotation.Bean;
@@ -58,28 +44,17 @@
@Configuration
@Import(
value = {
- ActiveViamPropertyFromSpringConfig.class,
- JwtRestServiceConfig.class,
JwtConfig.class,
ManagerDescriptionConfig.class,
// Pivot
ActivePivotWithDatastoreConfig.class,
- NoWriteDatastoreServiceConfig.class,
- FullAccessBranchPermissionsManagerConfig.class,
- ActivePivotServicesConfig.class,
- ActiveViamRestServicesConfig.class,
- ActiveViamWebSocketServicesConfig.class,
- ActivePivotXmlaServletConfig.class,
// Content server
ContentServiceConfig.class,
- LocalI18nConfig.class,
- ActiveUiResourceServerConfig.class,
// Specific to monitoring server
SecurityConfig.class,
- UserConfig.class,
SourceConfig.class,
})
public class MacServerConfig {
@@ -143,28 +118,6 @@ public JMXEnabler jmxMonitoringConnectorEnabler() {
return new JMXEnabler("StatisticSource", this.sourceConfig);
}
- /**
- * Enable JMX Monitoring for the Datastore.
- *
- * @return the {@link JMXEnabler} attached to the datastore
- */
- @Bean
- public JMXEnabler jmxDatastoreEnabler() {
- return new JMXEnabler(this.datastoreConfig.database());
- }
-
- /**
- * Enable JMX Monitoring for ActivePivot Components.
- *
- * @return the {@link JMXEnabler} attached to the activePivotManager
- */
- @Bean
- public JMXEnabler jmxActivePivotEnabler() {
- startManager();
-
- return new JMXEnabler(new DynamicActivePivotManagerMBean(apConfig.activePivotManager()));
- }
-
/**
* [Bean] JMX Bean to export bookmarks.
*
@@ -174,32 +127,4 @@ public JMXEnabler jmxActivePivotEnabler() {
public JMXEnabler jmxBookmarkEnabler() {
return new JMXEnabler("Bookmark", this.contentServiceConfig);
}
-
- /**
- * Enable JMX Monitoring for the ContentService.
- *
- * @return the {@link JMXEnabler} attached to the Content Service
- */
- @Bean
- public JMXEnabler jmxActivePivotContentServiceEnabler() {
- // to allow operations from the JMX bean
- return new JMXEnabler(
- new DynamicActivePivotContentServiceMBean(
- this.apContentServiceConfig.activePivotContentService(),
- this.apConfig.activePivotManager()));
- }
-
- /**
- * Enable Memory JMX Monitoring.
- *
- * @return the {@link JMXEnabler} attached to the memory analysis service.
- */
- @Bean
- public JMXEnabler jmxMemoryMonitoringServiceEnabler() {
- return new JMXEnabler(
- new MemoryAnalysisService(
- this.datastoreConfig.database(),
- this.apConfig.activePivotManager(),
- Paths.get(System.getProperty("java.io.tmpdir"))));
- }
}
diff --git a/src/main/java/com/activeviam/mac/cfg/impl/ManagerDescriptionConfig.java b/src/main/java/com/activeviam/mac/cfg/impl/ManagerDescriptionConfig.java
index a5a3bc45..21c863d1 100644
--- a/src/main/java/com/activeviam/mac/cfg/impl/ManagerDescriptionConfig.java
+++ b/src/main/java/com/activeviam/mac/cfg/impl/ManagerDescriptionConfig.java
@@ -7,45 +7,44 @@
package com.activeviam.mac.cfg.impl;
-import com.activeviam.builders.StartBuilding;
-import com.activeviam.comparators.ReverseEpochViewComparator;
-import com.activeviam.copper.ICopperContext;
-import com.activeviam.copper.api.Copper;
-import com.activeviam.copper.api.CopperMeasure;
-import com.activeviam.copper.api.CopperMeasureToAggregateAbove;
-import com.activeviam.copper.api.CopperStore;
+import com.activeviam.activepivot.copper.api.Copper;
+import com.activeviam.activepivot.copper.api.CopperMeasure;
+import com.activeviam.activepivot.copper.api.CopperMeasureToAggregateAbove;
+import com.activeviam.activepivot.copper.api.CopperStore;
+import com.activeviam.activepivot.core.datastore.api.builder.StartBuilding;
+import com.activeviam.activepivot.core.impl.api.contextvalues.QueriesResultLimit;
+import com.activeviam.activepivot.core.impl.api.contextvalues.QueriesTimeLimit;
+import com.activeviam.activepivot.core.impl.internal.util.impl.MdxNamingUtil;
+import com.activeviam.activepivot.core.intf.api.copper.ICopperContext;
+import com.activeviam.activepivot.core.intf.api.cube.hierarchy.IDimension;
+import com.activeviam.activepivot.core.intf.api.cube.hierarchy.IHierarchy;
+import com.activeviam.activepivot.core.intf.api.cube.metadata.ILevelInfo;
+import com.activeviam.activepivot.core.intf.api.cube.metadata.LevelIdentifier;
+import com.activeviam.activepivot.core.intf.api.description.IActivePivotInstanceDescription;
+import com.activeviam.activepivot.core.intf.api.description.IActivePivotManagerDescription;
+import com.activeviam.activepivot.core.intf.api.description.ISelectionDescription;
+import com.activeviam.activepivot.core.intf.api.description.builder.ICanBuildCubeDescription;
+import com.activeviam.activepivot.core.intf.api.description.builder.ICanStartBuildingMeasures;
+import com.activeviam.activepivot.core.intf.api.description.builder.IHasAtLeastOneMeasure;
+import com.activeviam.activepivot.core.intf.api.description.builder.ISelectionDescriptionBuilder;
+import com.activeviam.activepivot.core.intf.api.description.builder.dimension.ICanStartBuildingDimensions;
+import com.activeviam.activepivot.server.spring.api.config.IActivePivotManagerDescriptionConfig;
+import com.activeviam.activepivot.server.spring.api.config.IDatastoreSchemaDescriptionConfig;
+import com.activeviam.mac.comparators.ReverseEpochViewComparator;
import com.activeviam.database.api.schema.FieldPath;
-import com.activeviam.desc.build.ICanBuildCubeDescription;
-import com.activeviam.desc.build.ICanStartBuildingMeasures;
-import com.activeviam.desc.build.IHasAtLeastOneMeasure;
-import com.activeviam.desc.build.ISelectionDescriptionBuilder;
-import com.activeviam.desc.build.dimensions.ICanStartBuildingDimensions;
-import com.activeviam.formatter.ByteFormatter;
-import com.activeviam.formatter.ClassFormatter;
-import com.activeviam.formatter.PartitionIdFormatter;
+import com.activeviam.mac.formatter.ByteFormatter;
+import com.activeviam.mac.formatter.ClassFormatter;
+import com.activeviam.mac.formatter.PartitionIdFormatter;
import com.activeviam.mac.entities.ChunkOwner;
import com.activeviam.mac.entities.ChunkOwner.OwnerType;
import com.activeviam.mac.memory.DatastoreConstants;
import com.activeviam.mac.memory.MemoryAnalysisDatastoreDescriptionConfig;
import com.activeviam.mac.memory.MemoryAnalysisDatastoreDescriptionConfig.ParentType;
-import com.qfs.agg.impl.SingleValueFunction;
-import com.qfs.multiversion.IEpoch;
-import com.qfs.pivot.util.impl.MdxNamingUtil;
-import com.qfs.server.cfg.IActivePivotManagerDescriptionConfig;
-import com.qfs.server.cfg.IDatastoreSchemaDescriptionConfig;
-import com.qfs.store.Types;
-import com.quartetfs.biz.pivot.context.impl.QueriesResultLimit;
-import com.quartetfs.biz.pivot.context.impl.QueriesTimeLimit;
-import com.quartetfs.biz.pivot.cube.dimension.IDimension;
-import com.quartetfs.biz.pivot.cube.hierarchy.IHierarchy;
-import com.quartetfs.biz.pivot.cube.hierarchy.ILevelInfo;
-import com.quartetfs.biz.pivot.definitions.IActivePivotInstanceDescription;
-import com.quartetfs.biz.pivot.definitions.IActivePivotManagerDescription;
-import com.quartetfs.biz.pivot.definitions.ISelectionDescription;
-import com.quartetfs.fwk.format.impl.DateFormatter;
-import com.quartetfs.fwk.format.impl.NumberFormatter;
-import com.quartetfs.fwk.ordering.impl.NaturalOrderComparator;
-import com.quartetfs.fwk.ordering.impl.ReverseOrderComparator;
+import com.activeviam.tech.aggregation.internal.impl.SingleValueFunction;
+import com.activeviam.tech.chunks.api.types.Types;
+import com.activeviam.tech.core.api.format.IFormatter;
+import com.activeviam.tech.core.api.ordering.IComparator;
+import com.activeviam.tech.mvcc.api.IEpoch;
import java.time.Duration;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@@ -74,9 +73,9 @@ public class ManagerDescriptionConfig implements IActivePivotManagerDescriptionC
// region formatters
/** Formatter for Numbers. */
- public static final String NUMBER_FORMATTER = NumberFormatter.TYPE + "[#,###]";
+ public static final String NUMBER_FORMATTER = IFormatter.NUMBER_PLUGIN_KEY + "[#,###]";
/** Formatter for Percentages. */
- public static final String PERCENT_FORMATTER = NumberFormatter.TYPE + "[#.##%]";
+ public static final String PERCENT_FORMATTER = IFormatter.NUMBER_PLUGIN_KEY + "[#.##%]";
// endregion
// region dimensions
@@ -265,8 +264,7 @@ public IActivePivotManagerDescription managerDescription() {
}
private ISelectionDescription memorySelection() {
- return StartBuilding.selection(
- datastoreDescriptionConfig.datastoreSchemaDescription().asDatabaseSchema())
+ return StartBuilding.selection(datastoreDescriptionConfig.datastoreSchemaDescription())
.fromBaseStore(DatastoreConstants.CHUNK_STORE)
.withAllReachableFields(
allReachableFields -> {
@@ -379,7 +377,7 @@ private ICanBuildCubeDescription defineDimensio
"description", "The source folder name from which the statistics were retrieved")
.withLevelOfSameName()
.withPropertyName(DatastoreConstants.CHUNK__DUMP_NAME)
- .withComparator(NaturalOrderComparator.type)
+ .withComparator(IComparator.NATURAL_ORDER_PLUGIN_KEY)
.withLevelProperty(
"description", "The source folder name from which the statistics were retrieved")
.withHierarchy(DATE_HIERARCHY)
@@ -387,7 +385,7 @@ private ICanBuildCubeDescription defineDimensio
.withLevelOfSameName()
.withPropertyName(DatastoreConstants.APPLICATION__DATE)
.withType(ILevelInfo.LevelType.TIME)
- .withComparator(ReverseOrderComparator.type)
+ .withComparator(IComparator.DESCENDING_NATURAL_ORDER_PLUGIN_KEY)
.withLevelProperty("description", "Date at which statistics were retrieved")
.withDimension(AGGREGATE_PROVIDER_DIMENSION)
.withDimensionProperty(
@@ -434,7 +432,7 @@ private ICanBuildCubeDescription defineDimensio
.withLevelProperty(
"description",
"The internal epoch ID of the chunk (may be less than the epoch to view)")
- .withComparator(ReverseOrderComparator.type)
+ .withComparator(IComparator.DESCENDING_NATURAL_ORDER_PLUGIN_KEY)
.withHierarchy(BRANCH_HIERARCHY)
.withHierarchyProperty("description", "The branch of the chunk")
.withLevelOfSameName()
@@ -485,7 +483,7 @@ private IHasAtLeastOneMeasure nativeMeasures(ICanStartBuildingMeasures builder)
.withFormatter(NUMBER_FORMATTER)
.withinFolder(INTERNAL_FOLDER)
.withUpdateTimestamp()
- .withFormatter(DateFormatter.TYPE + "[HH:mm:ss]")
+ .withFormatter(IFormatter.DATE_PLUGIN_KEY + "[HH:mm:ss]")
.withinFolder(INTERNAL_FOLDER);
}
@@ -509,9 +507,21 @@ private void joinViewVersion(ICopperContext context) {
final CopperStore epochViewStore =
Copper.store(DatastoreConstants.EPOCH_VIEW_STORE)
.joinToCube()
- .withMapping(DatastoreConstants.OWNER__OWNER, OWNER_HIERARCHY)
- .withMapping(DatastoreConstants.CHUNK__DUMP_NAME, CHUNK_DUMP_NAME_LEVEL)
- .withMapping(DatastoreConstants.EPOCH_VIEW__BASE_EPOCH_ID, INTERNAL_EPOCH_ID_HIERARCHY);
+ .withMapping(
+ DatastoreConstants.OWNER__OWNER,
+ Copper.level(OWNER_DIMENSION, OWNER_HIERARCHY, OWNER_HIERARCHY))
+ .withMapping(
+ DatastoreConstants.CHUNK__DUMP_NAME,
+ Copper.level(
+ new LevelIdentifier(
+ CHUNK_DUMP_NAME_LEVEL, CHUNK_DUMP_NAME_LEVEL, CHUNK_DUMP_NAME_LEVEL)))
+ .withMapping(
+ DatastoreConstants.EPOCH_VIEW__BASE_EPOCH_ID,
+ Copper.level(
+ new LevelIdentifier(
+ VERSION_DIMENSION,
+ INTERNAL_EPOCH_ID_HIERARCHY,
+ INTERNAL_EPOCH_ID_HIERARCHY)));
Copper.newHierarchy(VERSION_DIMENSION, EPOCH_ID_HIERARCHY)
.fromField(epochViewStore.field(DatastoreConstants.EPOCH_VIEW__VIEW_EPOCH_ID))
@@ -524,9 +534,22 @@ private void joinReferencesToChunks(ICopperContext context) {
final CopperStore chunkToReferenceStore =
Copper.store(DatastoreConstants.REFERENCE_STORE)
.joinToCube()
- .withMapping(DatastoreConstants.REFERENCE_ID, CHUNK_REF_ID_LEVEL)
- .withMapping(DatastoreConstants.CHUNK__DUMP_NAME, CHUNK_DUMP_NAME_LEVEL)
- .withMapping(DatastoreConstants.VERSION__EPOCH_ID, INTERNAL_EPOCH_ID_HIERARCHY);
+ .withMapping(
+ DatastoreConstants.REFERENCE_ID,
+ Copper.level(
+ new LevelIdentifier(CHUNK_DIMENSION, CHUNK_REF_ID_LEVEL, CHUNK_REF_ID_LEVEL)))
+ .withMapping(
+ DatastoreConstants.CHUNK__DUMP_NAME,
+ Copper.level(
+ new LevelIdentifier(
+ CHUNK_DUMP_NAME_LEVEL, CHUNK_DUMP_NAME_LEVEL, CHUNK_DUMP_NAME_LEVEL)))
+ .withMapping(
+ DatastoreConstants.VERSION__EPOCH_ID,
+ Copper.level(
+ new LevelIdentifier(
+ VERSION_DIMENSION,
+ INTERNAL_EPOCH_ID_HIERARCHY,
+ INTERNAL_EPOCH_ID_HIERARCHY)));
Copper.newHierarchy(REFERENCE_NAMES_HIERARCHY)
.fromField(chunkToReferenceStore.field(DatastoreConstants.REFERENCE_NAME))
@@ -538,9 +561,23 @@ private void joinIndexesToChunks(ICopperContext context) {
final CopperStore chunkToIndexStore =
Copper.store(DatastoreConstants.INDEX_STORE)
.joinToCube()
- .withMapping(DatastoreConstants.INDEX_ID, CHUNK_INDEX_ID_LEVEL)
- .withMapping(DatastoreConstants.CHUNK__DUMP_NAME, CHUNK_DUMP_NAME_LEVEL)
- .withMapping(DatastoreConstants.VERSION__EPOCH_ID, INTERNAL_EPOCH_ID_HIERARCHY);
+ .withMapping(
+ DatastoreConstants.INDEX_ID,
+ Copper.level(
+ new LevelIdentifier(
+ CHUNK_DIMENSION, CHUNK_INDEX_ID_LEVEL, CHUNK_INDEX_ID_LEVEL)))
+ .withMapping(
+ DatastoreConstants.CHUNK__DUMP_NAME,
+ Copper.level(
+ new LevelIdentifier(
+ CHUNK_DUMP_NAME_LEVEL, CHUNK_DUMP_NAME_LEVEL, CHUNK_DUMP_NAME_LEVEL)))
+ .withMapping(
+ DatastoreConstants.VERSION__EPOCH_ID,
+ Copper.level(
+ new LevelIdentifier(
+ VERSION_DIMENSION,
+ INTERNAL_EPOCH_ID_HIERARCHY,
+ INTERNAL_EPOCH_ID_HIERARCHY)));
Copper.newHierarchy(INDEX_DIMENSION, INDEXED_FIELDS_HIERARCHY)
.fromField(chunkToIndexStore.field(DatastoreConstants.INDEX__FIELDS))
@@ -555,7 +592,9 @@ private void joinIndexesToChunks(ICopperContext context) {
private void bucketingHierarchies(final ICopperContext context) {
Copper.newHierarchy(OWNER_DIMENSION, OWNER_TYPE_HIERARCHY)
- .fromValues(Copper.level(OWNER_HIERARCHY).map(ChunkOwner::getType))
+ .fromValues(
+ Copper.level(OWNER_DIMENSION, OWNER_HIERARCHY, OWNER_HIERARCHY)
+ .map(ChunkOwner::getType))
.withMemberList((Object[]) OwnerType.values())
.withLevelOfSameName()
.publish(context);
@@ -728,18 +767,40 @@ private void dictionaryMeasures(ICopperContext context) {
final var chunkToDicoStore =
Copper.store(DatastoreConstants.DICTIONARY_STORE)
.joinToCube()
- .withMapping(DatastoreConstants.DICTIONARY_ID, CHUNK_DICO_ID_LEVEL)
- .withMapping(DatastoreConstants.CHUNK__DUMP_NAME, CHUNK_DUMP_NAME_LEVEL)
- .withMapping(DatastoreConstants.VERSION__EPOCH_ID, INTERNAL_EPOCH_ID_HIERARCHY);
+ .withMapping(
+ DatastoreConstants.DICTIONARY_ID,
+ Copper.level(
+ new LevelIdentifier(CHUNK_DIMENSION, CHUNK_DICO_ID_LEVEL, CHUNK_DICO_ID_LEVEL)))
+ .withMapping(
+ DatastoreConstants.CHUNK__DUMP_NAME,
+ Copper.level(
+ new LevelIdentifier(
+ CHUNK_DUMP_NAME_LEVEL, CHUNK_DUMP_NAME_LEVEL, CHUNK_DUMP_NAME_LEVEL)))
+ .withMapping(
+ DatastoreConstants.VERSION__EPOCH_ID,
+ Copper.level(
+ new LevelIdentifier(
+ VERSION_DIMENSION,
+ INTERNAL_EPOCH_ID_HIERARCHY,
+ INTERNAL_EPOCH_ID_HIERARCHY)));
Copper.agg(
chunkToDicoStore.field(DatastoreConstants.DICTIONARY_SIZE),
SingleValueFunction.PLUGIN_KEY)
- .filter(Copper.level(COMPONENT_HIERARCHY).eq(ParentType.DICTIONARY))
+ .filter(
+ Copper.level(
+ new LevelIdentifier(
+ COMPONENT_DIMENSION, COMPONENT_HIERARCHY, COMPONENT_HIERARCHY))
+ .eq(ParentType.DICTIONARY))
.per(
- Copper.level(INTERNAL_EPOCH_ID_HIERARCHY),
- Copper.level(CHUNK_DUMP_NAME_LEVEL),
- Copper.level(CHUNK_DICO_ID_LEVEL))
+ Copper.level(
+ new LevelIdentifier(
+ VERSION_DIMENSION, INTERNAL_EPOCH_ID_HIERARCHY, INTERNAL_EPOCH_ID_HIERARCHY)),
+ Copper.level(
+ new LevelIdentifier(
+ CHUNK_DUMP_NAME_LEVEL, CHUNK_DUMP_NAME_LEVEL, CHUNK_DUMP_NAME_LEVEL)),
+ Copper.level(
+ new LevelIdentifier(CHUNK_DIMENSION, CHUNK_DICO_ID_LEVEL, CHUNK_DICO_ID_LEVEL)))
.sum()
.as(DICTIONARY_SIZE)
.withFormatter(NUMBER_FORMATTER)
@@ -750,10 +811,10 @@ private void dictionaryMeasures(ICopperContext context) {
perChunkAggregation(DatastoreConstants.CHUNK__SIZE)
.max()
.per(
- Copper.hierarchy(OWNER_HIERARCHY).level(OWNER_HIERARCHY),
- Copper.hierarchy(FIELD_HIERARCHY).level(FIELD_HIERARCHY),
- Copper.hierarchy(PARTITION_HIERARCHY).level(PARTITION_HIERARCHY),
- Copper.hierarchy(CHUNK_CLASS_LEVEL).level(CHUNK_CLASS_LEVEL))
+ Copper.hierarchy(OWNER_DIMENSION, OWNER_HIERARCHY).level(OWNER_HIERARCHY),
+ Copper.hierarchy(FIELD_DIMENSION, FIELD_HIERARCHY).level(FIELD_HIERARCHY),
+ Copper.hierarchy(PARTITION_DIMENSION, PARTITION_HIERARCHY).level(PARTITION_HIERARCHY),
+ Copper.hierarchy(CHUNK_DIMENSION, CHUNK_CLASS_LEVEL).level(CHUNK_CLASS_LEVEL))
.min()
.as("Chunk size")
.withFormatter(NUMBER_FORMATTER)
@@ -775,7 +836,7 @@ private void vectorMeasures(ICopperContext context) {
.custom(SingleValueFunction.PLUGIN_KEY)
// The underlying vector block length should be the same for all the chunks of an
// application
- .per(Copper.level(FIELD_HIERARCHY))
+ .per(Copper.level(new LevelIdentifier(FIELD_DIMENSION, FIELD_HIERARCHY, FIELD_HIERARCHY)))
.doNotAggregateAbove()
.as(VECTOR_BLOCK_SIZE)
.withinFolder(VECTOR_FOLDER)
@@ -788,6 +849,10 @@ private CopperMeasureToAggregateAbove perChunkAggregation(final String fieldName
}
private CopperMeasureToAggregateAbove perChunkAggregation(final CopperMeasure measure) {
- return measure.per(Copper.level(CHUNK_ID_HIERARCHY), Copper.level(CHUNK_DUMP_NAME_LEVEL));
+ return measure.per(
+ Copper.level(new LevelIdentifier(CHUNK_DIMENSION, CHUNK_ID_HIERARCHY, CHUNK_ID_HIERARCHY)),
+ Copper.level(
+ new LevelIdentifier(
+ CHUNK_DUMP_NAME_LEVEL, CHUNK_DUMP_NAME_LEVEL, CHUNK_DUMP_NAME_LEVEL)));
}
}
diff --git a/src/main/java/com/activeviam/mac/cfg/impl/NoWriteDatastoreServiceConfig.java b/src/main/java/com/activeviam/mac/cfg/impl/NoWriteDatastoreServiceConfig.java
deleted file mode 100644
index 18e6e4e6..00000000
--- a/src/main/java/com/activeviam/mac/cfg/impl/NoWriteDatastoreServiceConfig.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * (C) ActiveViam 2019
- * ALL RIGHTS RESERVED. This material is the CONFIDENTIAL and PROPRIETARY
- * property of ActiveViam. Any unauthorized use
- * reproduction or transfer of this material is strictly prohibited
- */
-
-package com.activeviam.mac.cfg.impl;
-
-import com.qfs.desc.ITablePermissions;
-import com.qfs.desc.ITableSecurity;
-import com.qfs.service.store.impl.ADatabaseServiceConfig;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import org.springframework.context.annotation.Configuration;
-
-/** Configuration preventing any edition to the datastore from the remote services. */
-@Configuration
-public class NoWriteDatastoreServiceConfig extends ADatabaseServiceConfig {
-
- /**
- * A constant for store security.
- *
- *
This allows to read any fields but forbids all updates.
- */
- protected static final ITableSecurity defaultStoreSecurity =
- new ITableSecurity() {
-
- @Override
- public boolean isDeletingRecordsAllowed() {
- return false;
- }
-
- @Override
- public boolean isAddingNewRecordsAllowed() {
- return false;
- }
-
- @Override
- public ITablePermissions getTablePermissions() {
- return new ITablePermissions() {
-
- @Override
- public Set getTableWriterRoles() {
- return Collections.emptySet();
- }
-
- @Override
- public Set getTableReaderRoles() {
- return Collections.emptySet();
- }
-
- @Override
- public boolean canWriteField(String field, Set roles) {
- return false;
- }
-
- @Override
- public boolean canReadField(String field, Set roles) {
- return true;
- }
- };
- }
- };
- /**
- * A constant for the map which will always return the same store security, also defined as a
- * constant below.
- */
- protected static final Map storesSecurityMap =
- new HashMap<>() {
-
- private static final long serialVersionUID = 5_08_00L;
-
- @Override
- public ITableSecurity get(Object key) {
- return containsKey(key) ? super.get(key) : defaultStoreSecurity;
- }
- };
-
- /** Constructor. */
- public NoWriteDatastoreServiceConfig() {
- super(Collections.emptyMap(), Collections.emptyMap(), storesSecurityMap, DEFAULT_QUERY_TIMEOUT);
- }
-}
diff --git a/src/main/java/com/activeviam/mac/cfg/impl/RegistryInitializationConfig.java b/src/main/java/com/activeviam/mac/cfg/impl/RegistryInitializationConfig.java
new file mode 100644
index 00000000..1257ef77
--- /dev/null
+++ b/src/main/java/com/activeviam/mac/cfg/impl/RegistryInitializationConfig.java
@@ -0,0 +1,31 @@
+/*
+ * (C) ActiveViam 2024
+ * ALL RIGHTS RESERVED. This material is the CONFIDENTIAL and PROPRIETARY
+ * property of ActiveViam. Any unauthorized use,
+ * reproduction or transfer of this material is strictly prohibited
+ */
+
+package com.activeviam.mac.cfg.impl;
+
+import com.activeviam.tech.core.api.registry.Registry;
+import com.activeviam.tech.core.api.registry.Registry.RegistryContributions;
+import java.util.List;
+import org.springframework.boot.context.event.ApplicationStartingEvent;
+import org.springframework.context.ApplicationListener;
+
+/**
+ * Component initializing the registry as soon as possible when an application is starting.
+ *
+ * @author ActiveViam
+ */
+public class RegistryInitializationConfig implements ApplicationListener {
+
+ public void onApplicationEvent(final ApplicationStartingEvent ignored) {
+ setupRegistry();
+ }
+
+ public static void setupRegistry() {
+ Registry.initialize(
+ RegistryContributions.builder().packagesToScan(List.of("com.activeviam.mac")).build());
+ }
+}
diff --git a/src/main/java/com/activeviam/mac/cfg/impl/SourceConfig.java b/src/main/java/com/activeviam/mac/cfg/impl/SourceConfig.java
index 3a617deb..c9286c3b 100644
--- a/src/main/java/com/activeviam/mac/cfg/impl/SourceConfig.java
+++ b/src/main/java/com/activeviam/mac/cfg/impl/SourceConfig.java
@@ -10,18 +10,19 @@
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.toUnmodifiableList;
-import com.activeviam.fwk.ActiveViamRuntimeException;
+import com.activeviam.database.datastore.api.IDatastore;
+import com.activeviam.database.datastore.internal.impl.Datastore;
import com.activeviam.mac.Loggers;
import com.activeviam.mac.memory.AnalysisDatastoreFeeder;
-import com.qfs.jmx.JmxOperation;
-import com.qfs.monitoring.statistic.memory.IMemoryStatistic;
-import com.qfs.msg.csv.ICsvDataProvider;
-import com.qfs.msg.csv.IFileEvent;
-import com.qfs.msg.csv.filesystem.impl.DirectoryCSVTopic;
-import com.qfs.msg.impl.WatcherService;
-import com.qfs.pivot.monitoring.impl.MemoryStatisticSerializerUtil;
-import com.qfs.store.IDatastore;
-import com.qfs.store.impl.Datastore;
+import com.activeviam.mac.statistic.memory.deserializer.RetroCompatibleDeserializer;
+import com.activeviam.source.common.api.impl.WatcherService;
+import com.activeviam.source.csv.api.DirectoryCsvTopic;
+import com.activeviam.source.csv.api.ICsvDataProvider;
+import com.activeviam.source.csv.api.IFileEvent;
+import com.activeviam.tech.core.api.exceptions.ActiveViamRuntimeException;
+import com.activeviam.tech.core.internal.monitoring.JmxOperation;
+import com.activeviam.tech.observability.api.memory.IMemoryStatistic;
+import com.activeviam.tech.observability.internal.memory.AMemoryStatistic;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
@@ -40,7 +41,7 @@
import java.util.logging.Logger;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import org.springframework.beans.factory.annotation.Autowired;
+import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
@@ -52,20 +53,22 @@
* @author ActiveViam
*/
@Configuration
+@RequiredArgsConstructor
public class SourceConfig {
/** The name of the property that holds the path to the statistics folder. */
public static final String STATISTIC_FOLDER_PROPERTY = "statistic.folder";
private static final Logger LOGGER = Logger.getLogger(Loggers.LOADING);
+
/** Autowired {@link Datastore} to be fed by this source. */
- @Autowired protected IDatastore datastore;
+ private final IDatastore datastore;
/** Spring environment, automatically wired. */
- @Autowired protected Environment env;
+ private final Environment env;
/**
- * Provides a {@link DirectoryCSVTopic topic}.
+ * Provides a {@link DirectoryCsvTopic topic}.
*
*
The provided topic is based on the content of the folder defined by the {@code
* statistic.folder} environment property. By default, the property is defined in the {@code
@@ -77,7 +80,7 @@ public class SourceConfig {
*/
@Bean
@Lazy
- public DirectoryCSVTopic statisticTopic() throws IllegalStateException {
+ public DirectoryCsvTopic statisticTopic() throws IllegalStateException {
final String statisticFolder = this.env.getRequiredProperty(STATISTIC_FOLDER_PROPERTY);
final Path folderPath = Paths.get(statisticFolder);
if (LOGGER.isLoggable(Level.INFO)) {
@@ -92,7 +95,7 @@ public DirectoryCSVTopic statisticTopic() throws IllegalStateException {
+ folderPath.toAbsolutePath()
+ " is not a correct path to a valid directory.");
}
- return new DirectoryCSVTopic(
+ return new DirectoryCsvTopic(
"StatisticTopic",
null,
statisticFolder,
@@ -128,9 +131,14 @@ protected Path resolveDirectory(final String name) {
e);
}
}
- if (url == null
- || !Files.isDirectory(directory = Paths.get(URI.create(url.toExternalForm())))) {
- throw new IllegalArgumentException("'" + name + "' could not be resolved to a directory.");
+ if (url != null) {
+ directory = Paths.get(URI.create(url.toExternalForm()));
+ if (!Files.isDirectory(directory)) {
+ throw new IllegalArgumentException(
+ "'" + name + "' could not be resolved to a directory.");
+ }
+ } else {
+ throw new IllegalArgumentException("could not find '" + name + "' in the classpath.");
}
}
return directory;
@@ -206,15 +214,15 @@ private Map> collectDumpFiles(
}
private Path getStatisticFolder() {
- return resolveDirectory(this.env.getRequiredProperty("statistic.folder"));
+ return resolveDirectory(this.env.getRequiredProperty(STATISTIC_FOLDER_PROPERTY));
}
private void loadDumps(final Map> dumpFiles) {
dumpFiles.forEach(
(dumpName, entry) -> {
try {
- final Stream inputs =
- entry.stream().parallel().map(this::readStatisticFile);
+ final Stream inputs =
+ entry.stream().parallel().map(RetroCompatibleDeserializer::readStatisticFile);
final String message = feedDatastore(inputs, dumpName);
LOGGER.info(message);
} catch (final Exception e) {
@@ -223,21 +231,6 @@ private void loadDumps(final Map> dumpFiles) {
});
}
- private IMemoryStatistic readStatisticFile(final Path file) {
- try {
- if (LOGGER.isLoggable(Level.FINE)) {
- LOGGER.fine("Reading statistics from " + file.toAbsolutePath());
- }
- final IMemoryStatistic read = MemoryStatisticSerializerUtil.readStatisticFile(file.toFile());
- if (LOGGER.isLoggable(Level.FINE)) {
- LOGGER.fine("Statistics read from " + file.toAbsolutePath());
- }
- return read;
- } catch (final IOException ioe) {
- throw new RuntimeException("Cannot read statistics from " + file);
- }
- }
-
/**
* Feeds the {@link SourceConfig#datastore datastore} with a stream of {@link IMemoryStatistic}.
*
@@ -246,9 +239,8 @@ private IMemoryStatistic readStatisticFile(final Path file) {
* @return message to the user
*/
public String feedDatastore(
- final Stream memoryStatistics, final String dumpName) {
- final var info =
- new AnalysisDatastoreFeeder(dumpName).loadInto(this.datastore, memoryStatistics);
+ final Stream memoryStatistics, final String dumpName) {
+ final var info = new AnalysisDatastoreFeeder(dumpName, datastore).loadInto(memoryStatistics);
if (info.isPresent()) {
return "Commit successful for dump " + dumpName + " at epoch " + info.get().getId() + ".";
} else {
diff --git a/src/main/java/com/activeviam/mac/cfg/security/impl/ASecurityConfig.java b/src/main/java/com/activeviam/mac/cfg/security/impl/ASecurityConfig.java
deleted file mode 100644
index c6548e8d..00000000
--- a/src/main/java/com/activeviam/mac/cfg/security/impl/ASecurityConfig.java
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * (C) ActiveViam 2017-2020
- * ALL RIGHTS RESERVED. This material is the CONFIDENTIAL and PROPRIETARY
- * property of ActiveViam. Any unauthorized use,
- * reproduction or transfer of this material is strictly prohibited
- */
-
-package com.activeviam.mac.cfg.security.impl;
-
-import com.activeviam.security.cfg.ICorsConfig;
-import com.qfs.content.service.IContentService;
-import com.qfs.jwt.service.IJwtService;
-import com.qfs.server.cfg.IJwtConfig;
-import com.qfs.server.cfg.impl.VersionServicesConfig;
-import com.qfs.servlet.handlers.impl.NoRedirectLogoutSuccessHandler;
-import com.quartetfs.biz.pivot.security.IAuthorityComparator;
-import com.quartetfs.biz.pivot.security.impl.AuthorityComparatorAdapter;
-import com.quartetfs.fwk.ordering.impl.CustomComparator;
-import java.util.Collections;
-import java.util.List;
-import javax.servlet.Filter;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.core.env.Environment;
-import org.springframework.http.HttpStatus;
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
-import org.springframework.security.config.annotation.authentication.configuration.EnableGlobalAuthentication;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.builders.WebSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
-import org.springframework.security.crypto.factory.PasswordEncoderFactories;
-import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
-import org.springframework.security.crypto.password.NoOpPasswordEncoder;
-import org.springframework.security.crypto.password.PasswordEncoder;
-import org.springframework.security.web.AuthenticationEntryPoint;
-import org.springframework.security.web.authentication.HttpStatusEntryPoint;
-import org.springframework.security.web.context.SecurityContextPersistenceFilter;
-import org.springframework.security.web.firewall.StrictHttpFirewall;
-import org.springframework.web.cors.CorsConfiguration;
-import org.springframework.web.cors.CorsConfigurationSource;
-import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
-
-/**
- * Generic implementation for security configuration of a server hosting ActivePivot, or Content
- * server or ActiveMonitor.
- *
- *
This class contains methods:
- *
- *
- *
To define authorized users,
- *
To enable anonymous user access,
- *
To configure the JWT filter,
- *
To configure the security for Version service.
- *
- *
- * @author ActiveViam
- */
-@EnableGlobalAuthentication
-@Configuration
-public abstract class ASecurityConfig implements ICorsConfig {
-
- /** Set to true to allow anonymous access. */
- public static final boolean useAnonymous = false;
-
- /** Authentication Bean Name. */
- public static final String BASIC_AUTH_BEAN_NAME = "basicAuthenticationEntryPoint";
-
- /** ActivePivot Cookie Name. */
- public static final String AP_COOKIE_NAME = "AP_JSESSIONID";
-
- /** Name of the User Role. */
- public static final String ROLE_USER = "ROLE_USER";
-
- /** Name of the Admin Role. */
- public static final String ROLE_ADMIN = "ROLE_ADMIN";
-
- /** Name of the Tech Role. */
- public static final String ROLE_TECH = "ROLE_TECH";
-
- /** Name of the ContentService Root Role. */
- public static final String ROLE_CS_ROOT = IContentService.ROLE_ROOT;
-
- /** The address the UI is exposed to. */
- public static final String ACTIVEUI_ADDRESS = "activeui.address";
- /** The User Configuration. */
- @Autowired protected UserConfig userDetailsConfig;
-
- /** The JWT Configuration. */
- @Autowired protected IJwtConfig jwtConfig;
- /** The name of the Environment to use. */
- @Autowired protected Environment env;
-
- /**
- * As of Spring Security 5.0, the way the passwords are encoded must be specified. When logging,
- * the input password will be encoded and compared with the stored encoded password. To determine
- * which encoding function was used to encode the password, the stored encoded passwords are
- * prefixed with the id of the encoding function.
- *
- *
In order to avoid reformatting existing passwords in databases one can set the default
- * PasswordEncoder to use for stored passwords that are not prefixed. This is the
- * role of the following function.
- *
- * @return The {@link PasswordEncoder} to encode passwords with.
- */
- @Bean
- @SuppressWarnings({"deprecation", "unused"})
- public PasswordEncoder passwordEncoder() {
- PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
- ((DelegatingPasswordEncoder) passwordEncoder)
- .setDefaultPasswordEncoderForMatches(NoOpPasswordEncoder.getInstance());
- return passwordEncoder;
- }
-
- /**
- * Returns the default {@link AuthenticationEntryPoint} to use for the fallback basic HTTP
- * authentication.
- *
- * @return The default {@link AuthenticationEntryPoint} for the fallback HTTP basic
- * authentication.
- */
- @Bean(name = BASIC_AUTH_BEAN_NAME)
- public AuthenticationEntryPoint basicAuthenticationEntryPoint() {
- return new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED);
- }
-
- /**
- * Configures the authentication of the whole application.
- *
- *
This binds the defined user service to the authentication and sets the source for JWT
- * tokens.
- *
- * @param auth Spring builder to manage authentication
- * @throws Exception in case of error
- */
- @Autowired
- public void configureGlobal(final AuthenticationManagerBuilder auth) throws Exception {
- auth.eraseCredentials(false)
- // Add an LDAP authentication provider instead of this to support LDAP
- .userDetailsService(this.userDetailsConfig.userDetailsService())
- .and()
- // Required to allow JWT
- .authenticationProvider(this.jwtConfig.jwtAuthenticationProvider());
- }
-
- /**
- * [Bean] Comparator for user roles.
- *
- *
- *
- * @return a comparator that indicates which authority/role prevails over another.
- */
- @Bean
- public IAuthorityComparator authorityComparator() {
- final CustomComparator comp = new CustomComparator<>();
- comp.setFirstObjects(Collections.singletonList(ROLE_USER));
- comp.setLastObjects(Collections.singletonList(ROLE_ADMIN));
- return new AuthorityComparatorAdapter(comp);
- }
-
- @Override
- public List getAllowedOrigins() {
- return Collections.singletonList(env.getRequiredProperty(ACTIVEUI_ADDRESS));
- }
-
- /**
- * [Bean] Spring standard way of configuring CORS.
- *
- *
This simply forwards the configuration of {@link ICorsConfig} to Spring security system.
- *
- * @return the configuration for the application.
- */
- @Bean
- public CorsConfigurationSource corsConfigurationSource() {
- final CorsConfiguration configuration = new CorsConfiguration();
- configuration.setAllowedOrigins(getAllowedOrigins());
- configuration.setAllowedHeaders(getAllowedHeaders());
- configuration.setExposedHeaders(getExposedHeaders());
- configuration.setAllowedMethods(getAllowedMethods());
- configuration.setAllowCredentials(true);
-
- final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
- source.registerCorsConfiguration("/**", configuration);
-
- return source;
- }
-
- /**
- * Common configuration for {@link HttpSecurity}.
- *
- * @author ActiveViam
- */
- public abstract static class AWebSecurityConfigurer extends WebSecurityConfigurerAdapter {
-
- /** {@code true} to enable the logout URL. */
- protected final boolean logout;
- /** The name of the cookie to clear. */
- protected final String cookieName;
-
- /** The name of the Environment to use. */
- @Autowired protected Environment env;
-
- /** The ApplicationContext which contains the Beans. */
- @Autowired protected ApplicationContext context;
-
- /** This constructor does not enable the logout URL. */
- public AWebSecurityConfigurer() {
- this(null);
- }
-
- /**
- * This constructor enables the logout URL.
- *
- * @param cookieName the name of the cookie to clear
- */
- public AWebSecurityConfigurer(String cookieName) {
- this.logout = cookieName != null;
- this.cookieName = cookieName;
- }
-
- /**
- * {@inheritDoc}
- *
- *
This configures a new firewall accepting `%` in URLs, as none of the core services encode
- * information in URL. This prevents from double-decoding exploits.
- * The firewall is also configured to accept `\` - backslash - as none of ActiveViam APIs offer
- * to manipulate files from URL parameters.
- * Yet, nor `/` and `.` - slash and point - are accepted, as it may trick the REGEXP matchers
- * used for security. Support for those two characters can be added at your own risk, by
- * extending this method. As far as ActiveViam APIs are concerned, `/` and `.` in URL parameters
- * do not represent any risk. `;` - semi-colon - is also not supported, for various APIs end up
- * target an actual database, and because this character is less likely to be used.
- */
- @Override
- public void configure(WebSecurity web) throws Exception {
- super.configure(web);
-
- final StrictHttpFirewall firewall = new StrictHttpFirewall();
- firewall.setAllowUrlEncodedPercent(true);
- firewall.setAllowBackSlash(true);
-
- firewall.setAllowUrlEncodedSlash(false);
- firewall.setAllowUrlEncodedPeriod(false);
- firewall.setAllowSemicolon(false);
- web.httpFirewall(firewall);
- }
-
- @Override
- protected final void configure(final HttpSecurity http) throws Exception {
- final Filter jwtFilter = this.context.getBean(IJwtConfig.class).jwtFilter();
-
- http
- // As of Spring Security 4.0, CSRF protection is enabled by default.
- .csrf()
- .disable()
- .cors()
- .and()
- // To allow authentication with JWT (Required for ActiveUI)
- .addFilterAfter(jwtFilter, SecurityContextPersistenceFilter.class);
-
- if (this.logout) {
- // Configure logout URL
- http.logout()
- .permitAll()
- .deleteCookies(this.cookieName)
- .invalidateHttpSession(true)
- .logoutSuccessHandler(new NoRedirectLogoutSuccessHandler());
- }
-
- if (useAnonymous) {
- // Handle anonymous users. The granted authority ROLE_USER
- // will be assigned to the anonymous request
- http.anonymous().principal("guest").authorities(ROLE_USER);
- }
-
- doConfigure(http);
- }
-
- /**
- * Applies the specific configuration for the endpoint.
- *
- * @param http the http endpoint to configure.
- * @throws Exception in case of error.
- * @see #configure(HttpSecurity)
- */
- protected abstract void doConfigure(HttpSecurity http) throws Exception;
- }
-
- /**
- * Configuration for Version service to allow anyone to access this service.
- *
- * @author ActiveViam
- * @see HttpStatusEntryPoint
- */
- public abstract static class AVersionSecurityConfigurer extends WebSecurityConfigurerAdapter {
-
- /** The autowired Spring context. */
- @Autowired protected ApplicationContext context;
-
- @Override
- protected void configure(HttpSecurity http) throws Exception {
-
- http.antMatcher(VersionServicesConfig.REST_API_URL_PREFIX + "/**")
- // As of Spring Security 4.0, CSRF protection is enabled by default.
- .csrf()
- .disable()
- .cors()
- .and()
- .authorizeRequests()
- .antMatchers("/**")
- .permitAll();
- }
- }
-}
diff --git a/src/main/java/com/activeviam/mac/cfg/security/impl/ActiveUiSecurityConfigurer.java b/src/main/java/com/activeviam/mac/cfg/security/impl/ActiveUiSecurityConfigurer.java
deleted file mode 100644
index 1b3a23e9..00000000
--- a/src/main/java/com/activeviam/mac/cfg/security/impl/ActiveUiSecurityConfigurer.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * (C) ActiveViam 2017
- * ALL RIGHTS RESERVED. This material is the CONFIDENTIAL and PROPRIETARY
- * property of ActiveViam. Any unauthorized use,
- * reproduction or transfer of this material is strictly prohibited
- */
-
-package com.activeviam.mac.cfg.security.impl;
-
-import static com.activeviam.mac.cfg.security.impl.ASecurityConfig.ACTIVEUI_ADDRESS;
-
-import com.activeviam.mac.cfg.security.impl.ASecurityConfig.AWebSecurityConfigurer;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.core.annotation.Order;
-import org.springframework.http.HttpMethod;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-
-/**
- * To expose the login page of ActiveUI.
- *
- * @author ActiveViam
- */
-@Configuration
-@Order(1)
-public class ActiveUiSecurityConfigurer extends AWebSecurityConfigurer {
-
- @Override
- protected void doConfigure(HttpSecurity http) throws Exception {
- final String activeUiUrl = env.getRequiredProperty(ACTIVEUI_ADDRESS);
- http
- // Only theses URLs must be handled by this HttpSecurity
- .regexMatcher(activeUiUrl)
- .authorizeRequests()
- // The order of the matchers matters
- .regexMatchers(HttpMethod.OPTIONS, activeUiUrl)
- .permitAll()
- .regexMatchers(HttpMethod.GET, activeUiUrl)
- .permitAll();
- // this allows pre-flight cross-origin requests
- http.cors();
- // Authorizing pages to be embedded in iframes to have ActiveUI in ActiveMonitor UI
- http.headers().frameOptions().disable();
- }
-}
diff --git a/src/main/java/com/activeviam/mac/cfg/security/impl/CorsConfig.java b/src/main/java/com/activeviam/mac/cfg/security/impl/CorsConfig.java
new file mode 100644
index 00000000..cb5ca029
--- /dev/null
+++ b/src/main/java/com/activeviam/mac/cfg/security/impl/CorsConfig.java
@@ -0,0 +1,56 @@
+/*
+ * (C) ActiveViam 2017-2020
+ * ALL RIGHTS RESERVED. This material is the CONFIDENTIAL and PROPRIETARY
+ * property of ActiveViam. Any unauthorized use,
+ * reproduction or transfer of this material is strictly prohibited
+ */
+
+package com.activeviam.mac.cfg.security.impl;
+
+import com.activeviam.web.spring.api.config.ICorsConfig;
+import java.util.Collections;
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
+import org.springframework.security.config.annotation.authentication.configuration.EnableGlobalAuthentication;
+import org.springframework.web.cors.CorsConfiguration;
+
+/**
+ * Generic implementation for security configuration of a server hosting ActivePivot, or Content server or
+ * ActiveMonitor.
+ *
+ *
This class contains methods:
+ *
+ *
+ *
To define authorized users,
+ *
To enable anonymous user access,
+ *
To configure the JWT filter,
+ *
To configure the security for Version service.
+ *
+ *
+ * @author ActiveViam
+ */
+@EnableGlobalAuthentication
+@Configuration
+public class CorsConfig implements ICorsConfig {
+
+ /**
+ * The name of the Environment to use.
+ */
+ protected Environment env;
+
+ /**
+ * The address the UI is exposed to.
+ */
+ public static final String ACTIVEUI_ADDRESS = "activeui.address";
+
+ public CorsConfig(@Autowired Environment env) {
+ this.env = env;
+ }
+
+ @Override
+ public List getAllowedOrigins() {
+ return Collections.singletonList(env.getProperty(ACTIVEUI_ADDRESS, CorsConfiguration.ALL));
+ }
+}
diff --git a/src/main/java/com/activeviam/mac/cfg/security/impl/InMemoryUserDetailsManagerBuilder.java b/src/main/java/com/activeviam/mac/cfg/security/impl/InMemoryUserDetailsManagerBuilder.java
deleted file mode 100644
index d8e006dd..00000000
--- a/src/main/java/com/activeviam/mac/cfg/security/impl/InMemoryUserDetailsManagerBuilder.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * (C) ActiveViam 2015
- * ALL RIGHTS RESERVED. This material is the CONFIDENTIAL and PROPRIETARY
- * property of ActiveViam. Any unauthorized use,
- * reproduction or transfer of this material is strictly prohibited
- */
-
-package com.activeviam.mac.cfg.security.impl;
-
-import java.util.ArrayList;
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
-import org.springframework.security.config.annotation.authentication.configurers.provisioning.InMemoryUserDetailsManagerConfigurer;
-import org.springframework.security.config.annotation.authentication.configurers.provisioning.UserDetailsManagerConfigurer;
-import org.springframework.security.core.userdetails.UserDetailsService;
-import org.springframework.security.provisioning.InMemoryUserDetailsManager;
-import org.springframework.security.provisioning.UserDetailsManager;
-
-/**
- * An In-memory {@link UserDetailsService} builder which can be used without {@link
- * AuthenticationManagerBuilder} contrary to {@link InMemoryUserDetailsManagerConfigurer}.
- *
- * @author ActiveViam
- */
-public class InMemoryUserDetailsManagerBuilder
- extends UserDetailsManagerConfigurer<
- AuthenticationManagerBuilder, InMemoryUserDetailsManagerBuilder> {
-
- /** Creates a new instance. */
- public InMemoryUserDetailsManagerBuilder() {
- super(new InMemoryUserDetailsManager(new ArrayList<>()));
- }
-
- @Override
- public void configure(AuthenticationManagerBuilder builder) throws Exception {
- if (null != builder) {
- throw new IllegalArgumentException();
- }
- initUserDetailsService();
- }
-
- /**
- * Builds the In-memory {@link UserDetailsManager} and returns it.
- *
- * @return the built object
- */
- public UserDetailsManager build() {
- try {
- configure(null);
- return getUserDetailsService();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-}
diff --git a/src/main/java/com/activeviam/mac/cfg/security/impl/JwtSecurityConfigurer.java b/src/main/java/com/activeviam/mac/cfg/security/impl/JwtSecurityConfigurer.java
deleted file mode 100644
index 5b1c4160..00000000
--- a/src/main/java/com/activeviam/mac/cfg/security/impl/JwtSecurityConfigurer.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * (C) ActiveViam 2017
- * ALL RIGHTS RESERVED. This material is the CONFIDENTIAL and PROPRIETARY
- * property of ActiveViam. Any unauthorized use,
- * reproduction or transfer of this material is strictly prohibited
- */
-
-package com.activeviam.mac.cfg.security.impl;
-
-import com.qfs.server.cfg.impl.JwtRestServiceConfig;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.core.annotation.Order;
-import org.springframework.http.HttpMethod;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
-import org.springframework.security.web.AuthenticationEntryPoint;
-
-/**
- * To expose the JWT REST service.
- *
- * @author ActiveViam
- */
-@Configuration
-@Order(2) // Must be done before ContentServerSecurityConfigurer (because they match common URLs)
-public class JwtSecurityConfigurer extends WebSecurityConfigurerAdapter {
-
- /** The autowired Spring @link {@link ApplicationContext}. */
- @Autowired protected ApplicationContext context;
-
- @Override
- protected void configure(HttpSecurity http) throws Exception {
- final AuthenticationEntryPoint basicAuthenticationEntryPoint =
- this.context.getBean(ASecurityConfig.BASIC_AUTH_BEAN_NAME, AuthenticationEntryPoint.class);
- http.antMatcher(JwtRestServiceConfig.REST_API_URL_PREFIX + "/**")
- // As of Spring Security 4.0, CSRF protection is enabled by default.
- .csrf()
- .disable()
- .cors()
- .and()
- // Configure CORS
- .authorizeRequests()
- .antMatchers(HttpMethod.OPTIONS, "/**")
- .permitAll()
- .antMatchers("/**")
- .hasAnyAuthority(ASecurityConfig.ROLE_USER)
- .and()
- .httpBasic()
- .authenticationEntryPoint(basicAuthenticationEntryPoint);
- }
-}
diff --git a/src/main/java/com/activeviam/mac/cfg/security/impl/SecurityConfig.java b/src/main/java/com/activeviam/mac/cfg/security/impl/SecurityConfig.java
index 59b42e2c..541b6749 100644
--- a/src/main/java/com/activeviam/mac/cfg/security/impl/SecurityConfig.java
+++ b/src/main/java/com/activeviam/mac/cfg/security/impl/SecurityConfig.java
@@ -1,70 +1,125 @@
-/*
- * (C) ActiveViam 2019-2020
- * ALL RIGHTS RESERVED. This material is the CONFIDENTIAL and PROPRIETARY
- * property of ActiveViam. Any unauthorized use,
- * reproduction or transfer of this material is strictly prohibited
- */
-
package com.activeviam.mac.cfg.security.impl;
-import static com.qfs.QfsWebUtils.url;
-import static com.qfs.server.cfg.impl.ActivePivotRemotingServicesConfig.ID_GENERATOR_REMOTING_SERVICE;
-import static com.qfs.server.cfg.impl.ActivePivotRemotingServicesConfig.LICENSING_REMOTING_SERVICE;
-import static com.qfs.server.cfg.impl.ActivePivotRemotingServicesConfig.LONG_POLLING_REMOTING_SERVICE;
-import static com.qfs.server.cfg.impl.ActivePivotRestServicesConfig.PING_SUFFIX;
-import static com.qfs.server.cfg.impl.ActivePivotRestServicesConfig.REST_API_URL_PREFIX;
-
-import com.qfs.server.cfg.IActivePivotConfig;
-import com.quartetfs.biz.pivot.security.impl.UserDetailsServiceWrapper;
-import com.quartetfs.fwk.security.IUserDetailsService;
-import org.springframework.beans.factory.annotation.Autowired;
+import com.activeviam.tech.contentserver.storage.api.IContentService;
+import com.activeviam.web.spring.api.config.IJwtConfig;
+import com.activeviam.web.spring.api.jwt.JwtAuthenticationProvider;
+import lombok.RequiredArgsConstructor;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Import;
-import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.config.BeanIds;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.ProviderManager;
+import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.web.authentication.switchuser.SwitchUserFilter;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.User.UserBuilder;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.crypto.factory.PasswordEncoderFactories;
+import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
+import org.springframework.security.crypto.password.NoOpPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.provisioning.InMemoryUserDetailsManager;
+import org.springframework.security.web.AuthenticationEntryPoint;
+import org.springframework.security.web.authentication.HttpStatusEntryPoint;
+import org.springframework.security.web.firewall.StrictHttpFirewall;
-/**
- * Spring configuration fragment for security on an ActivePivot Server.
- *
- *
This configuration will in particular load:
- *
- *
- *
The service to authenticate users
- *
The Spring configuration that defines security on the Version RESTful service
- *
The Spring configuration that defines security on the Content server
- *
The Spring configuration that defines security on the ActivePivot server
- *
- *
- * @author ActiveViam
- */
-@Import(
- value = {
- ActiveUiSecurityConfigurer.class,
- JwtSecurityConfigurer.class,
- VersionSecurityConfigurer.class
- })
@Configuration
@EnableWebSecurity
-public class SecurityConfig extends ASecurityConfig {
+@RequiredArgsConstructor
+public class SecurityConfig {
+
+ /** Name of the User Role. */
+ public static final String ROLE_USER = "ROLE_USER";
+
+ /** Name of the Admin Role. */
+ public static final String ROLE_ADMIN = "ROLE_ADMIN";
/** Name of the Cookies of the MAC application. */
public static final String COOKIE_NAME = "MEMORY_ANALYSIS_CUBE";
/**
- * Returns the spring security bean user details service wrapper.
+ * [Bean] Create the users that can access the application.
+ *
+ * @return {@link UserDetailsService user data}
+ */
+ @Bean
+ public UserDetailsService userDetailsService(final PasswordEncoder passwordEncoder) {
+ final UserBuilder builder = User.builder().passwordEncoder(passwordEncoder::encode);
+ final InMemoryUserDetailsManager service = new InMemoryUserDetailsManager();
+ service.createUser(
+ builder
+ .username("admin")
+ .password("admin")
+ .authorities(ROLE_USER, ROLE_ADMIN, IContentService.ROLE_ROOT)
+ .build());
+ return service;
+ }
+
+ /**
+ * As of Spring Security 5.0, the way the passwords are encoded must be specified. When logging,
+ * the input password will be encoded and compared with the stored encoded password. To determine
+ * which encoding function was used to encode the password, the stored encoded passwords are
+ * prefixed with the id of the encoding function.
+ *
+ *
In order to avoid reformatting existing passwords in databases one can set the default
+ * PasswordEncoder to use for stored passwords that are not prefixed. This is the
+ * role of the following function.
+ *
+ * @return The {@link PasswordEncoder} to encode passwords with.
+ */
+ @Bean
+ @SuppressWarnings({"deprecation", "unused"})
+ public PasswordEncoder passwordEncoder() {
+ PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
+ ((DelegatingPasswordEncoder) passwordEncoder)
+ .setDefaultPasswordEncoderForMatches(NoOpPasswordEncoder.getInstance());
+ return passwordEncoder;
+ }
+
+ /**
+ * Returns the default {@link AuthenticationEntryPoint} to use for the fallback basic HTTP
+ * authentication.
*
- * @return the {@link IUserDetailsService} used as spring security bean user details service
- * wrapper.
+ * @return The default {@link AuthenticationEntryPoint} for the fallback HTTP basic
+ * authentication.
*/
@Bean
- public IUserDetailsService qfsUserDetailsService() {
- return new UserDetailsServiceWrapper(this.userDetailsConfig.userDetailsService());
+ public AuthenticationEntryPoint basicAuthenticationEntryPoint() {
+ return new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED);
+ }
+
+ /**
+ * Configures the authentication of the whole application.
+ *
+ *
This binds the defined user service to the authentication and sets the source for JWT
+ * tokens.
+ *
+ * @param inMemoryAuthenticationProvider the in-memory authentication provider
+ * @param jwtAuthenticationProvider is a provider which can perform authentication from the
+ * jwtService's tokens. Implementation from the {@link IJwtConfig} .
+ * @return the authentication manager
+ */
+ @Bean
+ public AuthenticationManager authenticationManager(
+ final JwtAuthenticationProvider jwtAuthenticationProvider,
+ final AuthenticationProvider inMemoryAuthenticationProvider) {
+ final ProviderManager providerManager =
+ new ProviderManager(inMemoryAuthenticationProvider, jwtAuthenticationProvider);
+ providerManager.setEraseCredentialsAfterAuthentication(false);
+
+ return providerManager;
+ }
+
+ @Bean
+ public AuthenticationProvider inMemoryAuthenticationProvider(
+ final UserDetailsService userDetailsService, final PasswordEncoder passwordEncoder) {
+ final var authenticationProvider = new DaoAuthenticationProvider();
+ authenticationProvider.setPasswordEncoder(passwordEncoder);
+ authenticationProvider.setUserDetailsService(userDetailsService);
+
+ return authenticationProvider;
}
/**
@@ -78,54 +133,27 @@ public ServletContextInitializer servletContextInitializer() {
}
/**
- * To expose the Pivot services.
+ * {@inheritDoc}
*
- * @author ActiveViam
+ *
This configures a new firewall accepting `%` in URLs, as none of the core services encode
+ * information in URL. This prevents from double-decoding exploits.
+ * The firewall is also configured to accept `\` - backslash - as none of ActiveViam APIs offer to
+ * manipulate files from URL parameters.
+ * Yet, nor `/` and `.` - slash and point - are accepted, as it may trick the REGEXP matchers used
+ * for security. Support for those two characters can be added at your own risk, by extending this
+ * method. As far as ActiveViam APIs are concerned, `/` and `.` in URL parameters do not represent
+ * any risk. `;` - semi-colon - is also not supported, for various APIs end up target an actual
+ * database, and because this character is less likely to be used.
*/
- @Configuration
- public static class ActivePivotSecurityConfigurer extends AWebSecurityConfigurer {
-
- /** The autowired Spring configuration for ActivePivot. */
- @Autowired protected IActivePivotConfig activePivotConfig;
-
- /** Constructor. */
- public ActivePivotSecurityConfigurer() {
- super(COOKIE_NAME);
- }
-
- @Override
- protected void doConfigure(HttpSecurity http) throws Exception {
- http.authorizeRequests()
- // The order of the matchers matters
- .antMatchers(HttpMethod.OPTIONS, REST_API_URL_PREFIX + "/**")
- .permitAll()
- // Spring remoting services used by AP live 3.4
- .antMatchers(url(ID_GENERATOR_REMOTING_SERVICE, "**"))
- .hasAnyAuthority(ROLE_USER, ROLE_TECH)
- .antMatchers(url(LONG_POLLING_REMOTING_SERVICE, "**"))
- .hasAnyAuthority(ROLE_USER, ROLE_TECH)
- .antMatchers(url(LICENSING_REMOTING_SERVICE, "**"))
- .hasAnyAuthority(ROLE_USER, ROLE_TECH)
- // The ping service is temporarily authenticated (see PIVOT-3149)
- .antMatchers(url(REST_API_URL_PREFIX, PING_SUFFIX))
- .hasAnyAuthority(ROLE_USER, ROLE_TECH)
- // REST services
- .antMatchers(REST_API_URL_PREFIX + "/**")
- .hasAnyAuthority(ROLE_USER)
- // One has to be a user for all the other URLs
- .antMatchers("/**")
- .hasAuthority(ROLE_USER)
- .and()
- .httpBasic()
- // SwitchUserFilter is the last filter in the chain. See FilterComparator class.
- .and()
- .addFilterAfter(this.activePivotConfig.contextValueFilter(), SwitchUserFilter.class);
- }
+ @Bean
+ public StrictHttpFirewall configureFirewall() {
+ final StrictHttpFirewall firewall = new StrictHttpFirewall();
+ firewall.setAllowUrlEncodedPercent(true);
+ firewall.setAllowBackSlash(true);
- @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
- @Override
- public AuthenticationManager authenticationManagerBean() throws Exception {
- return super.authenticationManagerBean();
- }
+ firewall.setAllowUrlEncodedSlash(false);
+ firewall.setAllowUrlEncodedPeriod(false);
+ firewall.setAllowSemicolon(false);
+ return firewall;
}
}
diff --git a/src/main/java/com/activeviam/mac/cfg/security/impl/UserConfig.java b/src/main/java/com/activeviam/mac/cfg/security/impl/UserConfig.java
deleted file mode 100644
index 9800b794..00000000
--- a/src/main/java/com/activeviam/mac/cfg/security/impl/UserConfig.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * (C) ActiveViam 2017
- * ALL RIGHTS RESERVED. This material is the CONFIDENTIAL and PROPRIETARY
- * property of ActiveViam. Any unauthorized use,
- * reproduction or transfer of this material is strictly prohibited
- */
-
-package com.activeviam.mac.cfg.security.impl;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.core.userdetails.UserDetailsService;
-
-/**
- * Spring configuration that defines the users and their associated roles in the Sandbox
- * application.
- *
- * @author ActiveViam
- */
-@Configuration
-public class UserConfig {
-
- /**
- * ROLE_KPI is added to users, to give them permission to read kpis created by other users in the
- * content server In order to "share" kpis created in the content server, the kpi reader role is
- * set to : ROLE_KPI.
- */
- public static final String ROLE_KPI = "ROLE_KPI";
-
- /**
- * [Bean] Create the users that can access the application.
- *
- * @return {@link UserDetailsService user data}
- */
- @Bean
- public UserDetailsService userDetailsService() {
- return new InMemoryUserDetailsManagerBuilder()
-
- // "Real users"
- .withUser("admin")
- .password("admin")
- .authorities(
- SecurityConfig.ROLE_USER,
- SecurityConfig.ROLE_ADMIN,
- ROLE_KPI,
- SecurityConfig.ROLE_CS_ROOT)
- .and()
-
- // We're done
- .build();
- }
-}
diff --git a/src/main/java/com/activeviam/mac/cfg/security/impl/VersionSecurityConfigurer.java b/src/main/java/com/activeviam/mac/cfg/security/impl/VersionSecurityConfigurer.java
deleted file mode 100644
index e3a4c1e1..00000000
--- a/src/main/java/com/activeviam/mac/cfg/security/impl/VersionSecurityConfigurer.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * (C) ActiveViam 2017
- * ALL RIGHTS RESERVED. This material is the CONFIDENTIAL and PROPRIETARY
- * property of ActiveViam. Any unauthorized use,
- * reproduction or transfer of this material is strictly prohibited
- */
-
-package com.activeviam.mac.cfg.security.impl;
-
-import org.springframework.context.annotation.Configuration;
-import org.springframework.core.annotation.Order;
-
-/**
- * To expose the Version REST service.
- *
- * @author ActiveViam
- */
-@Configuration
-@Order(3)
-public class VersionSecurityConfigurer extends ASecurityConfig.AVersionSecurityConfigurer {}
diff --git a/src/main/java/com/activeviam/comparators/ReverseEpochViewComparator.java b/src/main/java/com/activeviam/mac/comparators/ReverseEpochViewComparator.java
similarity index 89%
rename from src/main/java/com/activeviam/comparators/ReverseEpochViewComparator.java
rename to src/main/java/com/activeviam/mac/comparators/ReverseEpochViewComparator.java
index 4416de92..45d45d81 100644
--- a/src/main/java/com/activeviam/comparators/ReverseEpochViewComparator.java
+++ b/src/main/java/com/activeviam/mac/comparators/ReverseEpochViewComparator.java
@@ -5,13 +5,13 @@
* reproduction or transfer of this material is strictly prohibited
*/
-package com.activeviam.comparators;
+package com.activeviam.mac.comparators;
import com.activeviam.mac.statistic.memory.visitor.impl.DistributedEpochView;
import com.activeviam.mac.statistic.memory.visitor.impl.EpochView;
import com.activeviam.mac.statistic.memory.visitor.impl.RegularEpochView;
-import com.quartetfs.fwk.QuartetExtendedPluginValue;
-import com.quartetfs.fwk.ordering.IComparator;
+import com.activeviam.tech.core.api.ordering.IComparator;
+import com.activeviam.tech.core.api.registry.AtotiExtendedPluginValue;
/**
* A comparator for epoch views.
@@ -25,7 +25,7 @@
* cube ids first, and their epoch ids second (more recent epochs are lesser than older ones)
*
*/
-@QuartetExtendedPluginValue(intf = IComparator.class, key = ReverseEpochViewComparator.PLUGIN_KEY)
+@AtotiExtendedPluginValue(intf = IComparator.class, key = ReverseEpochViewComparator.PLUGIN_KEY)
public class ReverseEpochViewComparator implements IComparator {
/** The plugin key of the comparator. */
diff --git a/src/main/java/com/activeviam/formatter/ByteFormatter.java b/src/main/java/com/activeviam/mac/formatter/ByteFormatter.java
similarity index 90%
rename from src/main/java/com/activeviam/formatter/ByteFormatter.java
rename to src/main/java/com/activeviam/mac/formatter/ByteFormatter.java
index 2b745e7f..eb284192 100644
--- a/src/main/java/com/activeviam/formatter/ByteFormatter.java
+++ b/src/main/java/com/activeviam/mac/formatter/ByteFormatter.java
@@ -5,17 +5,17 @@
* reproduction or transfer of this material is strictly prohibited
*/
-package com.activeviam.formatter;
+package com.activeviam.mac.formatter;
-import com.quartetfs.fwk.QuartetExtendedPluginValue;
-import com.quartetfs.fwk.format.IFormatter;
+import com.activeviam.tech.core.api.format.IFormatter;
+import com.activeviam.tech.core.api.registry.AtotiExtendedPluginValue;
/**
* Formatter displaying byte amounts with decimal units.
*
* @author ActiveViam
*/
-@QuartetExtendedPluginValue(intf = IFormatter.class, key = ByteFormatter.KEY)
+@AtotiExtendedPluginValue(intf = IFormatter.class, key = ByteFormatter.KEY)
public class ByteFormatter implements IFormatter {
/** Plugin key. */
diff --git a/src/main/java/com/activeviam/formatter/ClassFormatter.java b/src/main/java/com/activeviam/mac/formatter/ClassFormatter.java
similarity index 84%
rename from src/main/java/com/activeviam/formatter/ClassFormatter.java
rename to src/main/java/com/activeviam/mac/formatter/ClassFormatter.java
index fddfd70d..edcf926c 100644
--- a/src/main/java/com/activeviam/formatter/ClassFormatter.java
+++ b/src/main/java/com/activeviam/mac/formatter/ClassFormatter.java
@@ -5,10 +5,10 @@
* reproduction or transfer of this material is strictly prohibited
*/
-package com.activeviam.formatter;
+package com.activeviam.mac.formatter;
-import com.quartetfs.fwk.QuartetExtendedPluginValue;
-import com.quartetfs.fwk.format.IFormatter;
+import com.activeviam.tech.core.api.format.IFormatter;
+import com.activeviam.tech.core.api.registry.AtotiExtendedPluginValue;
import java.util.Arrays;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@@ -18,7 +18,7 @@
*
* @author ActiveViam
*/
-@QuartetExtendedPluginValue(intf = IFormatter.class, key = ClassFormatter.KEY)
+@AtotiExtendedPluginValue(intf = IFormatter.class, key = ClassFormatter.KEY)
public class ClassFormatter implements IFormatter {
/** Plugin key. */
diff --git a/src/main/java/com/activeviam/formatter/PartitionIdFormatter.java b/src/main/java/com/activeviam/mac/formatter/PartitionIdFormatter.java
similarity index 79%
rename from src/main/java/com/activeviam/formatter/PartitionIdFormatter.java
rename to src/main/java/com/activeviam/mac/formatter/PartitionIdFormatter.java
index 022569a6..1f627d88 100644
--- a/src/main/java/com/activeviam/formatter/PartitionIdFormatter.java
+++ b/src/main/java/com/activeviam/mac/formatter/PartitionIdFormatter.java
@@ -5,18 +5,18 @@
* reproduction or transfer of this material is strictly prohibited
*/
-package com.activeviam.formatter;
+package com.activeviam.mac.formatter;
import com.activeviam.mac.memory.MemoryAnalysisDatastoreDescriptionConfig;
-import com.quartetfs.fwk.QuartetExtendedPluginValue;
-import com.quartetfs.fwk.format.IFormatter;
+import com.activeviam.tech.core.api.format.IFormatter;
+import com.activeviam.tech.core.api.registry.AtotiExtendedPluginValue;
/**
* Formatter for partitions.
*
* @author ActiveViam
*/
-@QuartetExtendedPluginValue(intf = IFormatter.class, key = PartitionIdFormatter.KEY)
+@AtotiExtendedPluginValue(intf = IFormatter.class, key = PartitionIdFormatter.KEY)
public class PartitionIdFormatter implements IFormatter {
/** Plugin key. */
diff --git a/src/main/java/com/activeviam/mac/memory/AnalysisDatastoreFeeder.java b/src/main/java/com/activeviam/mac/memory/AnalysisDatastoreFeeder.java
index 1eaefb7e..c3ff1554 100644
--- a/src/main/java/com/activeviam/mac/memory/AnalysisDatastoreFeeder.java
+++ b/src/main/java/com/activeviam/mac/memory/AnalysisDatastoreFeeder.java
@@ -7,7 +7,13 @@
package com.activeviam.mac.memory;
+import com.activeviam.database.api.conditions.BaseConditions;
+import com.activeviam.database.api.query.ListQuery;
import com.activeviam.database.api.schema.FieldPath;
+import com.activeviam.database.api.schema.IDataTable;
+import com.activeviam.database.datastore.api.IDatastore;
+import com.activeviam.database.datastore.api.transaction.IOpenedTransaction;
+import com.activeviam.database.datastore.api.transaction.stats.IDatastoreSchemaTransactionInformation;
import com.activeviam.mac.Loggers;
import com.activeviam.mac.entities.ChunkOwner;
import com.activeviam.mac.entities.DistributedCubeOwner;
@@ -15,14 +21,9 @@
import com.activeviam.mac.statistic.memory.visitor.impl.EpochView;
import com.activeviam.mac.statistic.memory.visitor.impl.FeedVisitor;
import com.activeviam.mac.statistic.memory.visitor.impl.RegularEpochView;
-import com.qfs.condition.impl.BaseConditions;
-import com.qfs.monitoring.statistic.memory.IMemoryStatistic;
-import com.qfs.store.IDatastore;
-import com.qfs.store.query.ICursor;
-import com.qfs.store.record.IRecordFormat;
-import com.qfs.store.record.IRecordReader;
-import com.qfs.store.transaction.IDatastoreSchemaTransactionInformation;
-import com.qfs.store.transaction.IOpenedTransaction;
+import com.activeviam.tech.observability.internal.memory.AMemoryStatistic;
+import com.activeviam.tech.records.api.ICursor;
+import com.activeviam.tech.records.api.IRecordReader;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
@@ -51,18 +52,23 @@ public class AnalysisDatastoreFeeder {
* statistics.
*/
private final Map> regularEpochsPerOwner;
+
/**
* A mapping giving for each distributed owner the epochs that were expressed in their statistics.
*/
private final Map> distributedEpochsPerOwner;
+ final IDatastore datastore;
+
/**
* Constructor.
*
* @param dumpName the dump name to assign to the statistic
+ * @param datastore
*/
- public AnalysisDatastoreFeeder(final String dumpName) {
+ public AnalysisDatastoreFeeder(final String dumpName, IDatastore datastore) {
this.dumpName = dumpName;
+ this.datastore = datastore;
this.datastoreEpochs = new HashSet<>();
this.regularEpochsPerOwner = new HashMap<>();
@@ -80,12 +86,12 @@ public AnalysisDatastoreFeeder(final String dumpName) {
* @return the record
*/
private static Object[] generateEpochViewTuple(
- final IRecordFormat recordFormat,
+ final IDataTable recordFormat,
final ChunkOwner owner,
final String dumpName,
final long baseEpochId,
final EpochView epochView) {
- final Object[] tuple = new Object[recordFormat.getFieldCount()];
+ final Object[] tuple = new Object[recordFormat.getFields().size()];
tuple[recordFormat.getFieldIndex(DatastoreConstants.EPOCH_VIEW__OWNER)] = owner;
tuple[recordFormat.getFieldIndex(DatastoreConstants.CHUNK__DUMP_NAME)] = dumpName;
tuple[recordFormat.getFieldIndex(DatastoreConstants.EPOCH_VIEW__BASE_EPOCH_ID)] = baseEpochId;
@@ -99,13 +105,13 @@ private static Object[] generateEpochViewTuple(
* @return the result of the transaction
*/
public Optional loadInto(
- final IDatastore datastore, final Stream extends IMemoryStatistic> stats) {
+ final Stream extends AMemoryStatistic> stats) {
return datastore.edit(transaction -> loadWithTransaction(transaction, stats));
}
/** Loads the provided statistics within an open transaction. */
public void loadWithTransaction(
- final IOpenedTransaction transaction, final Stream extends IMemoryStatistic> stats) {
+ final IOpenedTransaction transaction, final Stream extends AMemoryStatistic> stats) {
stats.forEach(stat -> feedChunk(transaction, stat));
completeTransaction(transaction);
}
@@ -115,12 +121,13 @@ public void loadWithTransaction(
*
* @param transaction the transaction to add facts to
*/
- private void feedChunk(final IOpenedTransaction transaction, final IMemoryStatistic statistic) {
+ private void feedChunk(final IOpenedTransaction transaction, final AMemoryStatistic statistic) {
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.fine("Start feeding the application with " + statistic);
}
- statistic.accept(new FeedVisitor(transaction.getMetadata(), transaction, this.dumpName));
+ statistic.accept(
+ new FeedVisitor(this.datastore.getCurrentSchema(), transaction, this.dumpName));
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.fine("Application processed " + statistic);
@@ -139,15 +146,17 @@ private void completeTransaction(final IOpenedTransaction transaction) {
* @param transaction the transaction to collect the epochs from
*/
private void collectEpochsFromOpenedTransaction(final IOpenedTransaction transaction) {
- final ICursor result =
- transaction
- .getQueryRunner()
- .forStore(DatastoreConstants.CHUNK_STORE)
+ final ListQuery query =
+ this.datastore
+ .getQueryManager()
+ .listQuery()
+ .forTable(DatastoreConstants.CHUNK_STORE)
.withCondition(
BaseConditions.equal(
FieldPath.of(DatastoreConstants.CHUNK__DUMP_NAME), this.dumpName))
- .selecting(DatastoreConstants.OWNER__OWNER, DatastoreConstants.VERSION__EPOCH_ID)
- .run();
+ .withTableFields(DatastoreConstants.OWNER__OWNER, DatastoreConstants.VERSION__EPOCH_ID)
+ .toQuery();
+ final ICursor result = transaction.getQueryRunner().listQuery(query).run();
for (final IRecordReader reader : result) {
final ChunkOwner owner = (ChunkOwner) reader.read(0);
@@ -173,12 +182,8 @@ private void replicateChunksForMissingEpochs(final IOpenedTransaction transactio
}
private void replicateDatastoreEpochs(final IOpenedTransaction transaction) {
- final IRecordFormat epochViewRecordFormat =
- transaction
- .getMetadata()
- .getStoreMetadata(DatastoreConstants.EPOCH_VIEW_STORE)
- .getStoreFormat()
- .getRecordFormat();
+ final var epochViewRecordFormat =
+ this.datastore.getCurrentSchema().getTable(DatastoreConstants.EPOCH_VIEW_STORE);
for (final var datastoreEpochId : this.datastoreEpochs) {
for (final ChunkOwner owner : this.regularEpochsPerOwner.keySet()) {
@@ -212,12 +217,8 @@ private void replicateDatastoreEpochs(final IOpenedTransaction transaction) {
}
private void replicateDistributedEpochs(final IOpenedTransaction transaction) {
- final IRecordFormat epochViewRecordFormat =
- transaction
- .getMetadata()
- .getStoreMetadata(DatastoreConstants.EPOCH_VIEW_STORE)
- .getStoreFormat()
- .getRecordFormat();
+ final var epochViewRecordFormat =
+ this.datastore.getCurrentSchema().getTable(DatastoreConstants.EPOCH_VIEW_STORE);
for (final ChunkOwner owner : this.distributedEpochsPerOwner.keySet()) {
final Collection epochs = this.distributedEpochsPerOwner.get(owner);
diff --git a/src/main/java/com/activeviam/mac/memory/ChunkRecordHandler.java b/src/main/java/com/activeviam/mac/memory/ChunkRecordHandler.java
index 6879fb50..4a8e7b22 100644
--- a/src/main/java/com/activeviam/mac/memory/ChunkRecordHandler.java
+++ b/src/main/java/com/activeviam/mac/memory/ChunkRecordHandler.java
@@ -7,14 +7,14 @@
package com.activeviam.mac.memory;
-import com.qfs.chunk.impl.TombStoneChunk;
-import com.qfs.desc.IDuplicateKeyHandler;
-import com.qfs.dic.IWritableDictionary;
-import com.qfs.store.IStoreMetadata;
-import com.qfs.store.record.IRecordFormat;
-import com.qfs.store.record.IRecordReader;
-import com.qfs.store.record.IWritableRecord;
-import com.qfs.store.record.impl.IDictionaryProvider;
+import com.activeviam.database.datastore.api.description.IDuplicateKeyHandler;
+import com.activeviam.database.datastore.api.description.IKeyEventContext;
+import com.activeviam.tech.chunks.internal.impl.TombStoneChunk;
+import com.activeviam.tech.dictionaries.api.IDictionaryProvider;
+import com.activeviam.tech.dictionaries.avinternal.IWritableDictionary;
+import com.activeviam.tech.records.api.IRecordFormat;
+import com.activeviam.tech.records.api.IRecordReader;
+import com.activeviam.tech.records.api.IWritableRecord;
/**
* {@link IDuplicateKeyHandler} implementation defining the process of dealing with duplicated
@@ -29,28 +29,16 @@ public class ChunkRecordHandler implements IDuplicateKeyHandler {
private int defaultRefId = -1;
private int defaultIdxId = -1;
- @Override
- public IRecordReader selectDuplicateKeyInDatastore(
- final IRecordReader duplicateRecord,
- final IRecordReader previousRecord,
- final IStoreMetadata storeMetadata,
- final IDictionaryProvider dictionaryProvider,
- final int[] uniqueIndexFields,
- final int partitionId) {
- return createMergedRecord(duplicateRecord, previousRecord, storeMetadata, dictionaryProvider);
- }
-
private IRecordReader createMergedRecord(
IRecordReader duplicateRecord,
IRecordReader previousRecord,
- IStoreMetadata storeMetadata,
- IDictionaryProvider dictionaryProvider) {
- init(storeMetadata, dictionaryProvider);
+ IKeyEventContext keyEventContext) {
final int currentPartition = getPartition(previousRecord);
- final long currentDicId = getDicId(previousRecord);
- final long currentRefId = getRefId(previousRecord);
- final long currentIdxId = getIdxId(previousRecord);
+ final int currentDicId = getDicId(previousRecord);
+ final int currentRefId = getRefId(previousRecord);
+ final int currentIdxId = getIdxId(previousRecord);
+ init(previousRecord, keyEventContext.getDictionaryProvider());
if (currentPartition == this.sharedPartitionId) {
// We cannot make any change
@@ -67,7 +55,7 @@ private IRecordReader createMergedRecord(
} else {
// We ignore TombStoneChunks as they are a singleton that has minimal memory footprint
// but don't work with the current MAC data model
- if (getChunkClassName(duplicateRecord, dictionaryProvider, storeMetadata)
+ if (getChunkClassName(duplicateRecord, keyEventContext.getDictionaryProvider())
.contains(TombStoneChunk.class.getName())) {
return duplicateRecord;
}
@@ -75,8 +63,7 @@ private IRecordReader createMergedRecord(
assert newPartition != MemoryAnalysisDatastoreDescriptionConfig.NO_PARTITION;
assert currentPartition != MemoryAnalysisDatastoreDescriptionConfig.NO_PARTITION;
- final int partitionIdx =
- storeMetadata.getFieldIndex(DatastoreConstants.CHUNK__PARTITION_ID);
+ final int partitionIdx = getPartition(newRecord);
newRecord.writeInt(partitionIdx, this.sharedPartitionId);
// Sanity check in case two Chunks have different parents which should never happen
@@ -101,26 +88,25 @@ private IRecordReader createMergedRecord(
}
private void init(
- final IStoreMetadata storeMetadata, final IDictionaryProvider dictionaryProvider) {
+ final IRecordReader recordReader, final IDictionaryProvider dictionaryProvider) {
if (this.sharedPartitionId < 0) {
- final int partitionIdx = storeMetadata.getFieldIndex(DatastoreConstants.CHUNK__PARTITION_ID);
+ final int dicIdIdx = getPartition(recordReader);
@SuppressWarnings("unchecked")
final IWritableDictionary