Disable schema metadata when performing SchemaActions.

Additionally, don't force refresh schemas if schema metadata is disabled.

Closes: #990
Closes: #1253

Original pull request: #1255.
This commit is contained in:
Ammar Khaku
2022-04-17 14:59:33 -07:00
committed by Mark Paluch
parent 7614fc6edb
commit 1d1505ab9a
4 changed files with 130 additions and 7 deletions

View File

@@ -67,6 +67,7 @@ import com.datastax.oss.driver.api.core.CqlSessionBuilder;
* @author John Blum
* @author Mark Paluch
* @author Tomasz Lelek
* @author Ammar Khaku
* @since 3.0
*/
public class CqlSessionFactoryBean
@@ -450,11 +451,20 @@ public class CqlSessionFactoryBean
this.session = buildSession(sessionBuilder);
executeCql(getStartupScripts().stream(), this.session);
performSchemaAction();
try {
SchemaRefreshUtils.withDisabledSchema(this.session, () -> {
executeCql(getStartupScripts().stream(), this.session);
performSchemaAction();
});
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new IllegalStateException("Unexpected checked exception thrown", e);
}
this.systemSession.refreshSchema();
this.session.refreshSchema();
if (this.systemSession.isSchemaMetadataEnabled()) {
this.systemSession.refreshSchema();
}
}
protected CqlSessionBuilder buildBuilder() {

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.cassandra.config;
import com.datastax.oss.driver.api.core.session.Session;
/**
* Utility methods for executing schema actions with refresh disabled.
*
* @author Ammar Khaku
*/
class SchemaRefreshUtils {
@FunctionalInterface
interface ThrowingRunnable {
void run() throws Exception;
}
/**
* Programmatically disables schema refreshes on the session and runs the provided Runnable,
* taking care to restore the previous state of schema refresh config on the provided session.
* Note that the session could have had schema refreshes enabled/disabled either
* programmatically or via config.
*/
static void withDisabledSchema(Session session, ThrowingRunnable r) throws Exception {
boolean schemaEnabledPreviously = session.isSchemaMetadataEnabled();
session.setSchemaMetadataEnabled(false);
r.run();
session.setSchemaMetadataEnabled(null); // triggers schema refresh if results in true
if (schemaEnabledPreviously != session.isSchemaMetadataEnabled()) {
// user may have set it programmatically so set it back programmatically
session.setSchemaMetadataEnabled(schemaEnabledPreviously);
}
}
}

View File

@@ -37,6 +37,7 @@ import com.datastax.oss.driver.api.core.CqlSession;
* keyspace before applying {@link SchemaAction schema actions} such as creating user-defined types and tables.
*
* @author Mark Paluch
* @author Ammar Khaku
* @since 3.0
* @see SessionFactoryInitializer
*/
@@ -128,9 +129,7 @@ public class SessionFactoryFactoryBean extends AbstractFactoryBean<SessionFactor
this.keyspacePopulator.populate(getObject().getSession());
}
performSchemaAction();
this.session.refreshSchema();
SchemaRefreshUtils.withDisabledSchema(session, this::performSchemaAction);
}
@Override

View File

@@ -0,0 +1,66 @@
/*
* Copyright 2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.cassandra.config;
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import com.datastax.oss.driver.api.core.session.Session;
/**
* Test suite of unit tests testing the contract and functionality of the {@link SchemaRefreshUtils} class.
*/
@ExtendWith(MockitoExtension.class)
class SchemaRefreshUtilsUnitTests {
@Mock Session session;
@Test
void withDisabledSchemaRevert() throws Exception {
when(session.isSchemaMetadataEnabled()).thenReturn(true);
SchemaRefreshUtils.withDisabledSchema(session, () -> {});
verify(session).setSchemaMetadataEnabled(false);
verify(session).setSchemaMetadataEnabled(null);
}
@Test
void withDisabledSchemaDisabledPreviously() throws Exception {
when(session.isSchemaMetadataEnabled()).thenReturn(false);
SchemaRefreshUtils.withDisabledSchema(session, () -> {});
verify(session).setSchemaMetadataEnabled(false);
verify(session).setSchemaMetadataEnabled(null);
}
@Test
void withDisabledSchemaDisabledProgrammaticallyPreviously() throws Exception {
when(session.isSchemaMetadataEnabled()).thenReturn(false).thenReturn(true);
SchemaRefreshUtils.withDisabledSchema(session, () -> {});
verify(session, times(2)).setSchemaMetadataEnabled(false);
verify(session).setSchemaMetadataEnabled(null);
}
@Test
void withDisabledSchemaEnabledProgrammaticallyPreviously() throws Exception {
when(session.isSchemaMetadataEnabled()).thenReturn(true).thenReturn(false);
SchemaRefreshUtils.withDisabledSchema(session, () -> {});
verify(session).setSchemaMetadataEnabled(true);
verify(session).setSchemaMetadataEnabled(null);
}
}