[RM]Feature#75745. Add th2serviceStorage
MODIFY
BackEnd/Core/sailfish-core/src/main/java/com/exactpro/sf/center/impl/PluginLoader.java
BackEnd/Core/sailfish-core/src/main/java/com/exactpro/sf/center/impl/PluginLoader.java
/******************************************************************************
- * Copyright 2009-2018 Exactpro (Exactpro Systems Limited)
+ * Copyright 2009-2021 Exactpro (Exactpro Systems Limited)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -112,6 +112,8 @@ public class PluginLoader {
private final ILoadableManager scriptReportLoader;
+ private final ILoadableManager serviceStorageLoader;
+
public PluginLoader(
IWorkspaceDispatcher wd,
ILoadableManager staticServiceManager,
@@ -128,7 +130,8 @@ public class PluginLoader {
PluginServiceLoader pluginServiceLoader,
IVersion coreVersion,
ILoadableManager messageStorageLoader,
- ILoadableManager scriptReportLoader) {
+ ILoadableManager scriptReportLoader,
+ ILoadableManager serviceStorageLoader) {
if (wd == null) {
throw new NullPointerException("IWorkspaceDispatcher can't be null");
}
@@ -149,6 +152,7 @@ public class PluginLoader {
this.coreVersion = coreVersion;
this.messageStorageLoader = messageStorageLoader;
this.scriptReportLoader = scriptReportLoader;
+ this.serviceStorageLoader = serviceStorageLoader;
this.pluginVersions = new ArrayList<>();
}
@@ -156,7 +160,7 @@ public class PluginLoader {
/**
* @deprecated please use {@link #PluginLoader(IWorkspaceDispatcher, ILoadableManager, ILoadableManager, ILoadableManager,
* PreprocessorLoader, ValidatorLoader, ILoadableManager, ILoadableManager, ILoadableManager, MatrixProviderHolder,
- * ILoadableManager, ILoadableManager, PluginServiceLoader, IVersion, ILoadableManager, ILoadableManager)}
+ * ILoadableManager, ILoadableManager, PluginServiceLoader, IVersion, ILoadableManager, ILoadableManager, ILoadableManager)}
*/
@Deprecated
public PluginLoader(
@@ -177,7 +181,7 @@ public class PluginLoader {
ILoadableManager messageStorageLoader) {
this(wd, staticServiceManager, actionManager,
dictionaryManager, preprocessorLoader, validatorLoader, adapterManager, dataManager, languageManager, matrixProviderHolder,
- matrixConverterManager, statisticsReportsLoader, pluginServiceLoader, coreVersion, messageStorageLoader, null);
+ matrixConverterManager, statisticsReportsLoader, pluginServiceLoader, coreVersion, messageStorageLoader, null, null);
}
public LoadInfo load() throws FileNotFoundException, WorkspaceSecurityException, SailfishURIException {
@@ -562,6 +566,19 @@ public class PluginLoader {
logger.info("Ignore scripts reports [No ScriptReportLoader]. Plugin: {}", pluginPath);
}
+ //
+ // Load Th2ServiceStorage
+ //
+ if (serviceStorageLoader != null) {
+ try {
+ serviceStorageLoader.load(loadableContext);
+ } catch (Exception e) {
+ throw new EPSCommonException(e);
+ }
+ } else {
+ logger.info("Ignore service storage [No ServiceStorageLoader]. Plugin: {}", pluginPath);
+ }
+
// Collect service description files
if(pluginServiceLoader != null) {
try {

MODIFY
BackEnd/Core/sailfish-core/src/main/java/com/exactpro/sf/center/impl/SFLocalContext.java
BackEnd/Core/sailfish-core/src/main/java/com/exactpro/sf/center/impl/SFLocalContext.java
/******************************************************************************
- * Copyright 2009-2018 Exactpro (Exactpro Systems Limited)
+ * Copyright 2009-2021 Exactpro (Exactpro Systems Limited)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -99,8 +99,10 @@ import com.exactpro.sf.storage.IStorage;
import com.exactpro.sf.storage.ITestScriptStorage;
import com.exactpro.sf.storage.IVariableSetStorage;
import com.exactpro.sf.storage.MessageStorageLoader;
+import com.exactpro.sf.storage.ServiceStorageLoader;
import com.exactpro.sf.storage.impl.AbstractMessageStorage;
import com.exactpro.sf.storage.impl.BroadcastMessageStorage;
+import com.exactpro.sf.storage.impl.BroadcastServiceStorage;
import com.exactpro.sf.storage.impl.DatabaseAuthStorage;
import com.exactpro.sf.storage.impl.DatabaseEnvironmentStorage;
import com.exactpro.sf.storage.impl.DatabaseMatrixStorage;
@@ -313,6 +315,8 @@ public class SFLocalContext implements ISFContext {
PluginServiceLoader pluginServiceLoader = new PluginServiceLoader();
MessageStorageLoader messageStorageLoader = new MessageStorageLoader();
+ ServiceStorageLoader serviceStorageLoader = new ServiceStorageLoader();
+
scriptReportLoader = new ScriptReportLoader();
// 5) Load core & plugins
@@ -332,7 +336,8 @@ public class SFLocalContext implements ISFContext {
pluginServiceLoader,
version,
messageStorageLoader,
- scriptReportLoader);
+ scriptReportLoader,
+ serviceStorageLoader);
LoadInfo loadInfo = pluginLoader.load();
loadInfo.appendClassPath(compilerClassPath);
@@ -341,7 +346,7 @@ public class SFLocalContext implements ISFContext {
messageStorage = createMessageStorage(envSettings, sessionFactory, dictionaryManager, messageStorageLoader.getSecondaryMessageStorages(workspaceDispatcher, envSettings, dictionaryManager));
disposables.add(messageStorage);
- serviceStorage = createServiceStorage(envSettings, sessionFactory, workspaceDispatcher, staticServiceManager, dictionaryManager, messageStorage);
+ serviceStorage = createServiceStorage(envSettings, sessionFactory, workspaceDispatcher, staticServiceManager, dictionaryManager, messageStorage, serviceStorageLoader.getSecondaryServiceStorages(workspaceDispatcher, envSettings, dictionaryManager));
disposables.add(serviceStorage);
this.serviceContext = new DefaultServiceContext(dictionaryManager, messageStorage, serviceStorage, loggingConfigurator, taskExecutor, dataManager, wd);
@@ -439,17 +444,22 @@ public class SFLocalContext implements ISFContext {
}
private IServiceStorage createServiceStorage(EnvironmentSettings envSettings, SessionFactory sessionFactory, IWorkspaceDispatcher workspaceDispatcher, IStaticServiceManager staticServiceManager, IDictionaryManager dictionaryManager,
- IMessageStorage messageStorage) {
+ IMessageStorage messageStorage, List<IServiceStorage> secondaryStorages) {
+ IServiceStorage primaryStorage;
switch(envSettings.getStorageType()) {
case DB:
- return new DatabaseServiceStorage(sessionFactory, staticServiceManager, dictionaryManager, messageStorage);
+ primaryStorage = new DatabaseServiceStorage(sessionFactory, staticServiceManager, dictionaryManager, messageStorage);
+ break;
case FILE:
- return new FileServiceStorage(envSettings.getFileStoragePath(), workspaceDispatcher, staticServiceManager, messageStorage);
+ primaryStorage = new FileServiceStorage(envSettings.getFileStoragePath(), workspaceDispatcher, staticServiceManager, messageStorage);
+ break;
case MEMORY:
- return new MemoryServiceStorage();
+ primaryStorage = new MemoryServiceStorage();
+ break;
default:
throw new EPSCommonException("Unsupported service storage type. Check your descriptor.xml file.");
}
+ return new BroadcastServiceStorage(primaryStorage, secondaryStorages);
}
private IEnvironmentStorage createEnvironmentStorage(EnvironmentSettings envSettings, IStorage storage, IWorkspaceDispatcher workspaceDispatcher) {

MODIFY
BackEnd/Core/sailfish-core/src/main/java/com/exactpro/sf/externalapi/ServiceFactory.java
BackEnd/Core/sailfish-core/src/main/java/com/exactpro/sf/externalapi/ServiceFactory.java
@@ -211,7 +211,7 @@ public class ServiceFactory implements IServiceFactory {
IVersion coreVersion = new CoreVersion();
PluginLoader pluginLoader = new PluginLoader(wd, staticServiceManager, null,
dictionaryManager, null, null, null, dataManager, null, null, null, null,
- null, coreVersion, null, null);
+ null, coreVersion, null, null, null);
pluginLoader.load();
this.marshalManager = new ServiceMarshalManager(staticServiceManager, dictionaryManager);

MODIFY
BackEnd/Core/sailfish-core/src/main/java/com/exactpro/sf/help/HelpBuilder.java
BackEnd/Core/sailfish-core/src/main/java/com/exactpro/sf/help/HelpBuilder.java
@@ -306,7 +306,7 @@ public class HelpBuilder {
}
PluginLoader pluginLoader = new PluginLoader(wd, staticServiceManager, actionManager, dictionaryManager, preprocessorLoader, validatorLoader,
- adapterManager, dataManager, languageManager, matrixProviderHolder, matrixConverterManager, statisticsReportLoader, null, version, null, null);
+ adapterManager, dataManager, languageManager, matrixProviderHolder, matrixConverterManager, statisticsReportLoader, null, version, null, null, null);
pluginLoader.load();

ADD
BackEnd/Core/sailfish-core/src/main/java/com/exactpro/sf/storage/IAbstractServiceStorageFactory.java
+/*******************************************************************************
+ * Copyright 2009-2021 Exactpro (Exactpro Systems Limited)
+ *
+ * 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
+ *
+ * http://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 com.exactpro.sf.storage;
+
+import com.exactpro.sf.configuration.IDictionaryManager;
+import com.exactpro.sf.configuration.workspace.IWorkspaceDispatcher;
+import com.exactpro.sf.scriptrunner.EnvironmentSettings;
+import com.exactpro.sf.storage.impl.AbstractMessageStorage;
+
+public interface IAbstractServiceStorageFactory {
+
+ /**
+ * Create secondary service storage
+ * @param environmentSettings Global settings of Sailfish
+ */
+ IServiceStorage createServiceStorage(IWorkspaceDispatcher dispatcher, EnvironmentSettings environmentSettings, IDictionaryManager dictionaryManager);
+
+}

ADD
BackEnd/Core/sailfish-core/src/main/java/com/exactpro/sf/storage/ServiceStorageLoader.java
+/*******************************************************************************
+ * Copyright 2009-2021 Exactpro (Exactpro Systems Limited)
+ *
+ * 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
+ *
+ * http://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 com.exactpro.sf.storage;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+import java.util.ServiceLoader;
+import java.util.stream.Collectors;
+
+import com.exactpro.sf.configuration.IDictionaryManager;
+import com.exactpro.sf.configuration.ILoadableManager;
+import com.exactpro.sf.configuration.ILoadableManagerContext;
+import com.exactpro.sf.configuration.workspace.IWorkspaceDispatcher;
+import com.exactpro.sf.scriptrunner.EnvironmentSettings;
+
+public class ServiceStorageLoader implements ILoadableManager {
+
+ private final List<IAbstractServiceStorageFactory> secondaryServiceStorageFactory;
+
+ public ServiceStorageLoader() {
+ this.secondaryServiceStorageFactory = new LinkedList<>();
+ }
+
+ @Override
+ public void load(ILoadableManagerContext context) throws Exception {
+ for (IAbstractServiceStorageFactory factory : ServiceLoader.load(IAbstractServiceStorageFactory.class, context.getClassLoaders()[0])) {
+ secondaryServiceStorageFactory.add(factory);
+ }
+ }
+
+ public List<IServiceStorage> getSecondaryServiceStorages(IWorkspaceDispatcher dispatcher, EnvironmentSettings environmentSettings, IDictionaryManager dictionaryManager){
+ return secondaryServiceStorageFactory
+ .stream()
+ .map(factory -> factory.createServiceStorage(dispatcher, environmentSettings, dictionaryManager))
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ public void finalize(ILoadableManagerContext context) throws Exception {}
+}

MODIFY
BackEnd/Core/sailfish-core/src/main/java/com/exactpro/sf/storage/impl/BroadcastMessageStorage.java
BackEnd/Core/sailfish-core/src/main/java/com/exactpro/sf/storage/impl/BroadcastMessageStorage.java
/*******************************************************************************
- * Copyright 2009-2020 Exactpro (Exactpro Systems Limited)
+ * Copyright 2009-2021 Exactpro (Exactpro Systems Limited)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,11 +19,10 @@ package com.exactpro.sf.storage.impl;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.LinkedList;
+import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
-import java.util.function.Supplier;
import com.exactpro.sf.common.messages.IHumanMessage;
import com.exactpro.sf.common.messages.IMessage;
@@ -50,7 +49,7 @@ public class BroadcastMessageStorage extends AbstractMessageStorage {
}
public BroadcastMessageStorage(AbstractMessageStorage primaryStorage, AbstractMessageStorage... secondaryStorages) {
- this(primaryStorage, secondaryStorages.length > 0 ? Arrays.asList(secondaryStorages) : null);
+ this(primaryStorage, secondaryStorages.length > 0 ? Arrays.asList(secondaryStorages) : Collections.emptyList());
}
@Override

ADD
BackEnd/Core/sailfish-core/src/main/java/com/exactpro/sf/storage/impl/BroadcastServiceStorage.java
+/******************************************************************************
+ * Copyright 2009-2021 Exactpro (Exactpro Systems Limited)
+ *
+ * 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
+ *
+ * http://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 com.exactpro.sf.storage.impl;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Consumer;
+
+import org.jetbrains.annotations.NotNull;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.exactpro.sf.center.IDisposable;
+import com.exactpro.sf.common.services.ServiceInfo;
+import com.exactpro.sf.common.services.ServiceName;
+import com.exactpro.sf.common.util.EPSCommonException;
+import com.exactpro.sf.services.ServiceDescription;
+import com.exactpro.sf.services.ServiceEvent;
+import com.exactpro.sf.storage.IServiceStorage;
+import com.exactpro.sf.storage.SortCriterion;
+import com.exactpro.sf.storage.StorageFilter;
+import com.exactpro.sf.storage.StorageResult;
+
+public class BroadcastServiceStorage implements IServiceStorage {
+
+ private static final Logger logger = LoggerFactory.getLogger(BroadcastServiceStorage.class);
+
+ private static final String ERROR_MESSAGE_ON_ADD_DESCRIPTION = "Can`t add service description to all storages";
+ private static final String ERROR_MESSAGE_ON_REMOVE_DESCRIPTION = "Can`t remove service description from all storages";
+ private static final String ERROR_MESSAGE_ON_UPDATE_DESCRIPTION = "Can`t update service description for all storages";
+ private static final String ERROR_MESSAGE_ON_ADD_EVENT = "Can`t add service event to all storages";
+ private static final String ERROR_MESSAGE_ON_REMOVE_EVENT = "Can`t remove service events from all storages";
+ private static final String ERROR_MESSAGE_ON_CLEAR_EVENT = "Can`t clear service events in all storages";
+ private static final String ERROR_MESSAGE_ON_DISPOSE = "Can`t dispose in all storages";
+
+ private final IServiceStorage primaryStorage;
+ private final List<IServiceStorage> writableStorages;
+
+ public BroadcastServiceStorage(IServiceStorage primaryStorage, List<IServiceStorage> secondaryStorages) {
+ this.primaryStorage = Objects.requireNonNull(primaryStorage, "Primary storage can`t be null");
+ List<ServiceDescription> serviceDescriptions = primaryStorage.getServiceDescriptions();
+ secondaryStorages.forEach(storage -> serviceDescriptions.forEach(storage::addServiceDescription));
+ writableStorages = new ArrayList<>();
+ writableStorages.add(this.primaryStorage);
+ writableStorages.addAll(Objects.requireNonNull(secondaryStorages, "Secondary storages can`t be null"));
+ }
+ public BroadcastServiceStorage(IServiceStorage primaryStorage, IServiceStorage... secondaryStorages) {
+ this(primaryStorage, secondaryStorages.length > 0 ? Arrays.asList(secondaryStorages) : Collections.emptyList());
+ }
+
+
+ @NotNull
+ @Override
+ public ServiceInfo lookupService(ServiceName serviceName) {
+ return primaryStorage.lookupService(serviceName);
+ }
+
+ @Override
+ public void addServiceDescription(ServiceDescription description) {
+ execute(serviceStorage -> serviceStorage.addServiceDescription(description), ERROR_MESSAGE_ON_ADD_DESCRIPTION);
+ }
+
+ @Override
+ public void removeServiceDescription(ServiceDescription description) {
+ execute(serviceStorage -> serviceStorage.removeServiceDescription(description), ERROR_MESSAGE_ON_REMOVE_DESCRIPTION);
+ }
+
+ @Override
+ public void removeServiceDescriptions(Iterator<ServiceDescription> iterator) {
+ execute(serviceStorage -> serviceStorage.removeServiceDescriptions(iterator), ERROR_MESSAGE_ON_REMOVE_DESCRIPTION);
+ }
+
+ @Override
+ public void updateServiceDescription(ServiceDescription description) {
+ execute(serviceStorage -> serviceStorage.updateServiceDescription(description), ERROR_MESSAGE_ON_UPDATE_DESCRIPTION);
+ }
+
+ @Override
+ public List<ServiceDescription> getServiceDescriptions() {
+ return primaryStorage.getServiceDescriptions();
+ }
+
+ @Override
+ public void addServiceEvent(ServiceDescription description, ServiceEvent event) {
+ execute(serviceStorage -> serviceStorage.addServiceEvent(description, event), ERROR_MESSAGE_ON_ADD_EVENT);
+ }
+
+ @Override
+ public long getEventsCount(ServiceDescription description, StorageFilter filter) {
+ return primaryStorage.getEventsCount(description, filter);
+ }
+
+ @Override
+ public StorageResult<ServiceEvent> getServiceEvents(ServiceDescription description, StorageFilter filter, int firstRecord, int size, List<SortCriterion> sorting) {
+ return primaryStorage.getServiceEvents(description, filter, firstRecord, size, sorting);
+ }
+
+ @Override
+ public void removeServiceEvents(ServiceDescription description) {
+ execute(serviceStorage -> serviceStorage.removeServiceEvents(description), ERROR_MESSAGE_ON_REMOVE_EVENT);
+ }
+
+ @Override
+ public void clearServiceEvents() {
+ execute(IServiceStorage::clearServiceEvents, ERROR_MESSAGE_ON_CLEAR_EVENT);
+ }
+
+ @Override
+ public void dispose() {
+ execute(IDisposable::dispose, ERROR_MESSAGE_ON_DISPOSE);
+ }
+
+ private void execute(Consumer<IServiceStorage> action, String errorMessage) {
+ EPSCommonException exception = null;
+ for (IServiceStorage storage : writableStorages) {
+ try {
+ action.accept(storage);
+ } catch (Exception e) {
+ logger.error(e.getMessage(), e);
+ if (exception == null) {
+ exception = new EPSCommonException(errorMessage);
+ }
+ exception.addSuppressed(e);
+ }
+ }
+
+ if (exception != null && exception.getSuppressed().length > 0) {
+ throw exception;
+ }
+ }
+}

[RM]Feature#75745. Add th2serviceStorage

Change-Id: I0ee821538b499bc994e0095a2ed0b1bd692200e1