blob: db674067f05b93e2875caabdfa1e0d3dac9c73bd [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 Parasoft.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Janusz Studzizba - initial API and implementation
* Dariusz Oszczedlowski - initial API and implementation
* Magdalena Gniewek - initial API and implementation
* Michal Wlodarczyk - initial API and implementation
* Angel Lopez(Tecnalia) - CDO Security activation
*******************************************************************************/
package org.eclipse.opencert.storage.cdo;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.sql.DataSource;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.server.CDOServerUtil;
import org.eclipse.emf.cdo.server.IRepository;
import org.eclipse.emf.cdo.server.IStore;
import org.eclipse.emf.cdo.server.IStoreAccessor.CommitContext;
import org.eclipse.emf.cdo.server.ITransaction;
import org.eclipse.emf.cdo.server.db.CDODBUtil;
import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
import org.eclipse.emf.cdo.server.net4j.CDONet4jServerUtil;
import org.eclipse.emf.cdo.server.security.ISecurityManager;
import org.eclipse.emf.cdo.server.security.SecurityManagerUtil;
import org.eclipse.emf.cdo.server.spi.security.InternalSecurityManager;
import org.eclipse.emf.cdo.server.spi.security.InternalSecurityManager.CommitHandler;
import org.eclipse.emf.cdo.server.spi.security.SecurityManagerFactory;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.spi.server.InternalRepository;
import org.eclipse.emf.cdo.server.internal.security.*;
import org.eclipse.net4j.acceptor.*;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.net4j.Net4jUtil;
import org.eclipse.net4j.db.IDBAdapter;
import org.eclipse.net4j.db.IDBConnectionProvider;
import org.eclipse.net4j.db.postgresql.PostgreSQLAdapter;
import org.eclipse.net4j.internal.db.DataSourceConnectionProvider;
import org.eclipse.net4j.jvm.JVMUtil;
import org.eclipse.net4j.tcp.TCPUtil;
import org.eclipse.net4j.util.container.IManagedContainer;
import org.eclipse.net4j.util.container.IPluginContainer;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
import org.eclipse.net4j.util.om.OMPlatform;
import org.eclipse.net4j.util.om.log.PrintLogHandler;
import org.eclipse.net4j.util.om.monitor.OMMonitor;
import org.eclipse.net4j.util.om.trace.PrintTraceHandler;
import org.eclipse.opencert.storage.cdo.messages.OpencertPersistenceMessagesProducer;
import org.eclipse.opencert.storage.cdo.messages.PersistenceEventMessage;
import org.eclipse.opencert.storage.cdo.messages.PersistenceEventType;
import org.eclipse.opencert.storage.cdo.property.OpencertPropertiesReader;
import org.postgresql.ds.PGSimpleDataSource;
//import org.h2.jdbcx.JdbcDataSource;
public class StandaloneCDOServer
{
private OpencertPersistenceMessagesProducer opencertPersistenceMessagesProducer;
private static final String TRUE = Boolean.TRUE.toString();
private OpencertPropertiesReader propertiesReader = OpencertPropertiesReader.getInstance();
private IRepository repository;
private final DataSource dataSource;
private DataSource createDataSource()
{
PGSimpleDataSource dataSource = new org.postgresql.ds.PGSimpleDataSource();
dataSource.setUser(propertiesReader.getDbUser());
dataSource.setPassword(propertiesReader.getDbPassword());
dataSource.setServerName(propertiesReader.getDbHost());
dataSource.setPortNumber(propertiesReader.getDbPort());
dataSource.setDatabaseName(propertiesReader.getDbName());
dataSource.setSocketTimeout(120*60);
dataSource.setTcpKeepAlive(true);
//dataSource.setMaxConnections(80);
return dataSource;
}
public static void main(String[] args) throws Exception
{
new StandaloneCDOServer();
System.out.println("Standalone CDO server running...");
try {
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
}
public StandaloneCDOServer()
{
this.dataSource = createDataSource();
init();
}
public void setOpencertPersistenceMessagesProducer(OpencertPersistenceMessagesProducer opencertPersistenceMessagesProducer)
{
this.opencertPersistenceMessagesProducer = opencertPersistenceMessagesProducer;
}
private void init()
{
OMPlatform.INSTANCE.setDebugging(false);
OMPlatform.INSTANCE.addTraceHandler(PrintTraceHandler.CONSOLE);
OMPlatform.INSTANCE.addLogHandler(PrintLogHandler.CONSOLE);
Net4jUtil.prepareContainer(IPluginContainer.INSTANCE);
TCPUtil.prepareContainer(IPluginContainer.INSTANCE);
CDONet4jServerUtil.prepareContainer(IPluginContainer.INSTANCE);
JVMUtil.prepareContainer(IPluginContainer.INSTANCE); // Register JVM factories
String name = "opencert";
IStore store = createStore(name);
Map<String, String> properties = createRepositoryProperties(name, propertiesReader.isCDOSecurityEnabled());
repository = CDOServerUtil.createRepository(name, store,
properties);
if(propertiesReader.isCDOSecurityEnabled()){
System.out.println("Security extension starting ...");
ISecurityManager securityManager;
try {
securityManager = createSecurity(repository);
initSecurity(securityManager);
} catch (Exception e) {
e.printStackTrace();
}
}
registerCommitHandler();
CDOServerUtil.addRepository(IPluginContainer.INSTANCE, repository);
Net4jUtil.getAcceptor(IPluginContainer.INSTANCE, "tcp", propertiesReader.getCDOServerAddress());
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
shutdown();
}
});
}
public static IManagedContainer getContainer()
{
return IPluginContainer.INSTANCE;
}
protected CommitHandler getHandler(IManagedContainer container, String token)
{
String factoryType;
String description;
int pos = token.indexOf('(');
if (pos == -1)
{
factoryType = token.trim();
description = null;
}
else
{
factoryType = token.substring(0, pos).trim();
description = token.substring(pos + 1, token.length() - 1).trim();
}
return (CommitHandler)container.getElement(CommitHandler.Factory.PRODUCT_GROUP, factoryType, description);
}
private void registerCommitHandler()
{
repository.addHandler(new IRepository.WriteAccessHandler()
{
@Override
public void handleTransactionBeforeCommitting(ITransaction transaction,
CommitContext commitContext, OMMonitor omMonitor) throws RuntimeException
{
//ignore
}
@Override
public void handleTransactionAfterCommitted(ITransaction transaction,
CommitContext commitContext, OMMonitor omMonitor)
{
InternalCDORevision[] newObjects = commitContext.getNewObjects();
if (newObjects.length != 0) {
for (InternalCDORevision internalCDORevision : newObjects) {
if (opencertPersistenceMessagesProducer != null) {
PersistenceEventMessage entityPersistenceEventMessage = new PersistenceEventMessage(
PersistenceEventType.CREATE,
internalCDORevision.getEClass(),
internalCDORevision.getID());
opencertPersistenceMessagesProducer.send(entityPersistenceEventMessage);
}
}
}
InternalCDORevision[] dirtyObjects = commitContext.getDirtyObjects();
if (dirtyObjects.length != 0) {
for (InternalCDORevision internalCDORevision : dirtyObjects) {
if (opencertPersistenceMessagesProducer != null) {
PersistenceEventMessage entityPersistenceEventMessage = new PersistenceEventMessage(
PersistenceEventType.UPDATE,
internalCDORevision.getEClass(),
internalCDORevision.getID());
opencertPersistenceMessagesProducer.send(entityPersistenceEventMessage);
}
}
}
Map<CDOID, EClass> detachedObjectTypes = commitContext.getDetachedObjectTypes();
if (detachedObjectTypes != null && detachedObjectTypes.size() > 0) {
for(Entry<CDOID, EClass> entry : detachedObjectTypes.entrySet()) {
if (opencertPersistenceMessagesProducer != null) {
PersistenceEventMessage entityPersistenceEventMessage = new PersistenceEventMessage(
PersistenceEventType.DELETE,
entry.getValue(),
entry.getKey());
opencertPersistenceMessagesProducer.send(entityPersistenceEventMessage);
}
}
}
}
});
}
private ISecurityManager createSecurity(IRepository repository) {
IManagedContainer managedContainer = IPluginContainer.INSTANCE;
String realmPath = "/security";
SecurityManagerUtil.prepareContainer(managedContainer);
ISecurityManager securityManager = SecurityManagerUtil.createSecurityManager(realmPath, managedContainer);
CommitHandler handler = getHandler(managedContainer, "home(/home)");
((InternalSecurityManager) securityManager).addCommitHandler(handler);
return securityManager;
}
private void initSecurity(ISecurityManager securityManager) {
if (securityManager instanceof InternalSecurityManager) {
((InternalSecurityManager) securityManager).setRepository((InternalRepository) repository);
LifecycleUtil.activate(securityManager);
}
}
public void shutdown()
{
System.out.println("Shutting down CDO server, please wait...");
LifecycleUtil.deactivate(repository);
LifecycleUtil.deactivate(IPluginContainer.INSTANCE);
System.out.println("Clean shutdown of CDO server done.");
}
private IStore createStore(String name)
{
IMappingStrategy mappingStrategy = CDODBUtil
.createHorizontalMappingStrategy(true, true);
applyMappingProperties(mappingStrategy);
IDBAdapter dbAdapter = new PostgreSQLAdapter();
IDBConnectionProvider dbConnectionProvider = new DataSourceConnectionProvider(dataSource,"postgres");
return CDODBUtil.createStore(mappingStrategy, dbAdapter, dbConnectionProvider);
}
private void applyMappingProperties(IMappingStrategy mappingStrategy)
{
Map<String, String> mappingProperties = new HashMap<>();
mappingProperties.put(IMappingStrategy.PROP_QUALIFIED_NAMES, TRUE);
mappingStrategy.setProperties(mappingProperties);
}
private static Map<String, String> createRepositoryProperties(String name, Boolean isAuditsActive)
{
Map<String, String> props = new HashMap<String, String>();
props.put(IRepository.Props.OVERRIDE_UUID, name);
props.put(IRepository.Props.SUPPORTING_AUDITS, isAuditsActive.toString());
props.put(IRepository.Props.SUPPORTING_BRANCHES, isAuditsActive.toString());
props.put(IRepository.Props.OPTIMISTIC_LOCKING_TIMEOUT, "10000");
return props;
}
}