Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zj/spring add configuration bean #672

Merged
merged 4 commits into from
Oct 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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