Skip to content

Commit

Permalink
Zj/spring add configuration bean (#672)
Browse files Browse the repository at this point in the history
* Add Configuration Bean into Spring project.
  • Loading branch information
zdenek-jonas authored Oct 26, 2023
1 parent 35b7303 commit 5c60356
Show file tree
Hide file tree
Showing 12 changed files with 425 additions and 46 deletions.
25 changes: 25 additions & 0 deletions docs/modules/misc/pages/integrations/spring-boot.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,31 @@ You have the opportunity to perform actions on the _StorageManager_ or root obje
- The _StorageManager_ is already started unless you specified the configuration value `one.microstream.auto-start=false`.
- If you have used the `@Storage` annotation on a class, the _StorageManager_ is already associated with an instance of that class as the Root object.

It is also possible to obtain the entire configuration within the `StorageManagerConfiguration` Bean, enabling you to directly create a foundation and storage manager. This can be helpful if you need to stop storage at runtime and then restart it.

[source]
----
@Component
public class ConfigurationBeanInject
{
@Autowired
StorageManagerConfiguration configuration;
@Autowired
StorageManagerProvider provider;
Root root = new Root();
void startStorage()
{
EmbeddedStorageFoundation<?> embeddedStorageFoundation = provider.embeddedStorageFoundation(configuration.getValues());
EmbeddedStorageManager storage = embeddedStorageFoundation.start(root));
...
}
----

== Root object

The root object can be indicated by using the `@Storage` annotation on the class. This annotation converts the POJO into a Spring bean (The annotation is a Spring Qualifier that makes the class also a _Component_).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ one.microstream.data-file-minimum-use-ratio=0.9
one.microstream.data-file-cleanup-head-file=true
one.microstream.entity-cache-timeout=1d

one.microstream.auto-start=false
one.microstream.auto-start=false
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package test.microstream.integrations.spring.boot;

/*-
* #%L
* microstream-integrations-spring-boot
* %%
* Copyright (C) 2019 - 2023 MicroStream Software
* %%
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License, v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is
* available at https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
* #L%
*/

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import one.microstream.integrations.spring.boot.types.config.StorageManagerConfiguration;
import one.microstream.integrations.spring.boot.types.config.StorageManagerProvider;
import one.microstream.storage.embedded.types.EmbeddedStorageFoundation;
import one.microstream.storage.embedded.types.EmbeddedStorageManager;

@SpringBootTest
public class ConfigurationBeanTest
{
@Autowired
StorageManagerConfiguration configuration;

@Autowired
StorageManagerProvider provider;

private final String TEST_SENTENCE = "I love MicroStream Spring Extension";

@Test
void testReloadData()
{
Assertions.assertNotNull(configuration);
Assertions.assertNotNull(provider);

EmbeddedStorageFoundation<?> embeddedStorageFoundation = provider.embeddedStorageFoundation(configuration.getValues());
TestData data = new TestData(TEST_SENTENCE);
try (EmbeddedStorageManager storage = embeddedStorageFoundation.start(data)) {
}

EmbeddedStorageFoundation<?> embeddedStorageFoundation2 = provider.embeddedStorageFoundation(configuration.getValues());
TestData data2 = new TestData();
try (EmbeddedStorageManager storage2 = embeddedStorageFoundation2.start(data2)) {
Assertions.assertEquals(TEST_SENTENCE, data2.getValue());
}
}

@Test
void testReloadDataWithoutFoundation()
{
Assertions.assertNotNull(configuration);
Assertions.assertNotNull(provider);

try (EmbeddedStorageManager storageManager = provider.create(configuration.getValues())) {
TestData data = new TestData(TEST_SENTENCE);
storageManager.start();
storageManager.setRoot(data);
storageManager.storeRoot();
}

try (EmbeddedStorageManager storageManager2 = provider.create(configuration.getValues())) {

TestData data2 = new TestData();
storageManager2.start();
TestData readData = (TestData) storageManager2.root();
Assertions.assertEquals(TEST_SENTENCE, readData.getValue());

}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package test.microstream.integrations.spring.boot;

/*-
* #%L
* microstream-integrations-spring-boot
* %%
* Copyright (C) 2019 - 2023 MicroStream Software
* %%
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License, v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is
* available at https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
* #L%
*/

public class TestData
{
private String value = "";

public TestData()
{
}

public TestData(String value)
{
this.value = value;
}

public String getValue()
{
return value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package one.microstream.integrations.spring.boot.types.config;

/*-
* #%L
* microstream-integrations-spring-boot
* %%
* Copyright (C) 2019 - 2023 MicroStream Software
* %%
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License, v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is
* available at https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
* #L%
*/

import java.util.HashMap;
import java.util.Map;

public class StorageManagerConfiguration
{
private Map<String, String> values;

public StorageManagerConfiguration()
{
}

public StorageManagerConfiguration(Map<String, String> values)
{
this.values = values;
}

public Map<String, String> getValues()
{
return values;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ public StorageManagerFactory(final StorageManagerProvider storageManagerProvider
this.storageManagerProvider = storageManagerProvider;
}

@Bean
@Lazy
@Primary
public StorageManagerConfiguration storageManagerConfiguration ()
{
return this.storageManagerProvider.prepareConfiguration();
}

@Bean
@Lazy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public StorageManagerProvider(
this.applicationContext = applicationContext;
}

private Map<String, String> readProperties(final String qualifier)
protected Map<String, String> readProperties(final String qualifier)
{
final MutablePropertySources sources = ((AbstractEnvironment) this.env).getPropertySources();

Expand Down Expand Up @@ -118,11 +118,28 @@ public EmbeddedStorageManager get(final String qualifier)
return this.storageManagers.computeIfAbsent(qualifier, this::create);
}

private EmbeddedStorageManager create(final String qualifier)
public EmbeddedStorageManager get(final String qualifier, Map<String, String> values)
{
return this.storageManagers.computeIfAbsent(qualifier, this::create);
}

protected StorageManagerConfiguration prepareConfiguration(final String qualifier)
{
return new StorageManagerConfiguration(this.normalizeProperties(this.readProperties(qualifier)));
}

protected StorageManagerConfiguration prepareConfiguration()
{
return new StorageManagerConfiguration(this.normalizeProperties(this.readProperties(PRIMARY_QUALIFIER)));
}

final Map<String, String> values = this.normalizeProperties(this.readProperties(qualifier));
public EmbeddedStorageManager create(Map<String, String> values)
{
return create(PRIMARY_QUALIFIER, values);
}

public EmbeddedStorageManager create(final String qualifier, Map<String, String> values)
{
final EmbeddedStorageFoundation<?> embeddedStorageFoundation = this.embeddedStorageFoundation(qualifier, values);

final MicrostreamConfigurationProperties configuration = new MicrostreamConfigurationProperties();
Expand All @@ -131,8 +148,6 @@ private EmbeddedStorageManager create(final String qualifier)
Binder.get(new EnvironmentFromMap(values))
.bind("", Bindable.ofInstance(configuration));

embeddedStorageFoundation.getConnectionFoundation()
.setClassLoaderProvider(typeName -> this.applicationContext.getClassLoader());

ByQualifier.filter(this.customizers, qualifier)
.forEach(c -> c.customize(embeddedStorageFoundation));
Expand All @@ -148,12 +163,20 @@ private EmbeddedStorageManager create(final String qualifier)
if (!this.hasRootDefined(qualifier))
{
// No @Storage,so we need to execute initializers now.
// Otherwise the StorageBeanFactory.createRootObject is responsible for calling the
// Otherwise, the StorageBeanFactory.createRootObject is responsible for calling the
ByQualifier.filter(this.initializers, qualifier)
.forEach(i -> i.initialize(storageManager));
}

return storageManager;

}

private EmbeddedStorageManager create(final String qualifier)
{
final Map<String, String> values = prepareConfiguration(qualifier).getValues();

return create(qualifier, values);
}

private boolean hasRootDefined(final String qualifier)
Expand All @@ -175,33 +198,32 @@ private boolean hasRootDefined(final String qualifier)

public EmbeddedStorageFoundation<?> embeddedStorageFoundation()
{
final Map<String, String> values = this.normalizeProperties(this.readProperties(PRIMARY_QUALIFIER));
final Map<String, String> values = prepareConfiguration(PRIMARY_QUALIFIER).getValues();
return this.embeddedStorageFoundation(PRIMARY_QUALIFIER, values);
}

public EmbeddedStorageFoundation<?> embeddedStorageFoundation(final Map<String, String> values)
{
return this.embeddedStorageFoundation(PRIMARY_QUALIFIER, values);
}

private EmbeddedStorageFoundation<?> embeddedStorageFoundation(final String qualifier, final Map<String, String> values)
public EmbeddedStorageFoundation<?> embeddedStorageFoundation(final String qualifier, final Map<String, String> values)
{
final EmbeddedStorageConfigurationBuilder builder = EmbeddedStorageConfigurationBuilder.New();

this.logger.debug("MicroStream configuration items: ");
values.forEach((key, value) ->
{
if (value != null)
{
if (key.contains("password"))
{
this.logger.debug(key + " : xxxxxx");
}
else
{
this.logger.debug(key + " : " + value);
}
builder.set(key, value);
}
});

values.forEach((key, value) -> {
if (value != null) {
String logValue = key.contains("password") ? "xxxxxx" : value;
this.logger.debug(key + " : " + logValue);
builder.set(key, value);
}
});

final EmbeddedStorageFoundation<?> storageFoundation = builder.createEmbeddedStorageFoundation();
storageFoundation.getConnectionFoundation()
.setClassLoaderProvider(typeName -> this.applicationContext.getClassLoader());
storageFoundation.setDataBaseName(qualifier);
return storageFoundation;

Expand Down
Loading

0 comments on commit 5c60356

Please sign in to comment.