add file storage management service

This commit is contained in:
Fredrik Teschke committed 2015-01-23 17:52:21 +01:00
1 parent 3edbbb04bb
commit 944614c1ac
19 files changed
+283 -90

No files matched your search

@@ -1,5 +1,8 @@
package com.sap.sailing.domain.racelog.tracking.test.mock;
import java.util.Collections;
import java.util.Set;
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
import com.sap.sse.common.TypeBasedServiceFinder;
@@ -16,4 +19,8 @@ public class MockEmptyServiceFinder<ServiceType> implements TypeBasedServiceFind
this.fallback = fallback;
}
@Override
public Set<ServiceType> findAllServices() {
return Collections.singleton(fallback);
}
}
@@ -1,5 +1,9 @@
package com.sap.sailing.domain.racelog.tracking.test.mock;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import com.sap.sailing.domain.persistence.impl.DomainObjectFactoryImpl;
import com.sap.sailing.domain.persistence.impl.MongoObjectFactoryImpl;
import com.sap.sailing.domain.persistence.racelog.tracking.GPSFixMongoHandler;
@@ -12,15 +16,22 @@ import com.sap.sse.common.TypeBasedServiceFinder;
public class MockGPSFixMongoServiceFinder implements TypeBasedServiceFinder<GPSFixMongoHandler> {
private final MongoObjectFactoryImpl mof = new MongoObjectFactoryImpl(null);
private final DomainObjectFactoryImpl dof = new DomainObjectFactoryImpl(null, null);
private final GPSFixMongoHandler movingHandler = new GPSFixMovingMongoHandlerImpl(mof, dof);
private final GPSFixMongoHandler handler = new GPSFixMongoHandlerImpl(mof, dof);
@Override
public GPSFixMongoHandler findService(String fixType) {
if (fixType.equals(GPSFixMovingImpl.class.getName())) return new GPSFixMovingMongoHandlerImpl(mof, dof);
if (fixType.equals(GPSFixImpl.class.getName())) return new GPSFixMongoHandlerImpl(mof, dof);
if (fixType.equals(GPSFixMovingImpl.class.getName())) return movingHandler;
if (fixType.equals(GPSFixImpl.class.getName())) return handler;
return null;
}
@Override
public void setFallbackService(GPSFixMongoHandler fallback) {
}
@Override
public Set<GPSFixMongoHandler> findAllServices() {
return new HashSet<GPSFixMongoHandler>(Arrays.asList(movingHandler, handler));
}
}
@@ -1,5 +1,8 @@
package com.sap.sailing.domain.racelog.tracking.test.mock;
import java.util.Collections;
import java.util.Set;
import com.sap.sse.common.TypeBasedServiceFinder;
public class MockServiceFinder<T> implements TypeBasedServiceFinder<T> {
@@ -20,4 +23,9 @@ public class MockServiceFinder<T> implements TypeBasedServiceFinder<T> {
public void setFallbackService(T fallback) {
this.fallback = fallback;
}
@Override
public Set<T> findAllServices() {
return Collections.singleton(handler);
}
}
@@ -1,5 +1,9 @@
package com.sap.sailing.server.gateway.serialization.racelog.tracking.impl;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import com.sap.sailing.domain.tracking.GPSFix;
import com.sap.sailing.domain.tracking.GPSFixMoving;
import com.sap.sailing.server.gateway.deserialization.impl.GPSFixJsonDeserializer;
@@ -15,11 +19,14 @@ import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
import com.sap.sse.common.TypeBasedServiceFinder;
public class GPSFixJsonServiceFinder implements TypeBasedServiceFinder<GPSFixJsonHandler> {
private final GPSFixJsonHandler gpsFixHandler = new GPSFixJsonHandlerImpl<GPSFix>(new GPSFixJsonDeserializer(), new GPSFixJsonSerializer());
private final GPSFixJsonHandler gpsFixMovingHandler = new GPSFixJsonHandlerImpl<GPSFixMoving>(new GPSFixMovingJsonDeserializer(), new GPSFixMovingJsonSerializer());
private final GPSFixJsonHandler gpsFixNmeaDTOHandler = new GPSFixJsonHandlerImpl<GPSFix>(new GPSFixNmeaDTOJsonDeserializer(), new GPSFixNmeaDTOJsonSerializer());
private final GPSFixJsonHandler gpsFixMovingNmeaDTOHandler = new GPSFixJsonHandlerImpl<GPSFixMoving>(new GPSFixMovingNmeaDTOJsonDeserializer(), new GPSFixMovingNmeaDTOJsonSerializer());
private final GPSFixJsonHandler gpsFixHandler = new GPSFixJsonHandlerImpl<GPSFix>(new GPSFixJsonDeserializer(),
new GPSFixJsonSerializer());
private final GPSFixJsonHandler gpsFixMovingHandler = new GPSFixJsonHandlerImpl<GPSFixMoving>(
new GPSFixMovingJsonDeserializer(), new GPSFixMovingJsonSerializer());
private final GPSFixJsonHandler gpsFixNmeaDTOHandler = new GPSFixJsonHandlerImpl<GPSFix>(
new GPSFixNmeaDTOJsonDeserializer(), new GPSFixNmeaDTOJsonSerializer());
private final GPSFixJsonHandler gpsFixMovingNmeaDTOHandler = new GPSFixJsonHandlerImpl<GPSFixMoving>(
new GPSFixMovingNmeaDTOJsonDeserializer(), new GPSFixMovingNmeaDTOJsonSerializer());
@Override
public GPSFixJsonHandler findService(String type) throws NoCorrespondingServiceRegisteredException {
@@ -33,13 +40,19 @@ public class GPSFixJsonServiceFinder implements TypeBasedServiceFinder<GPSFixJso
return gpsFixMovingNmeaDTOHandler;
}
throw new NoCorrespondingServiceRegisteredException(
"Only handlers for GPSFix, GPSFixMoving, GPSFixNmeaDTO, GPSFixMovingNmeaDTO are registered",
type, GPSFixJsonHandler.class.getSimpleName());
"Only handlers for GPSFix, GPSFixMoving, GPSFixNmeaDTO, GPSFixMovingNmeaDTO are registered", type,
GPSFixJsonHandler.class.getSimpleName());
}
@Override
public void setFallbackService(GPSFixJsonHandler fallback) {
}
@Override
public Set<GPSFixJsonHandler> findAllServices() {
return new HashSet<GPSFixJsonHandler>(Arrays.asList(gpsFixHandler, gpsFixMovingHandler,
gpsFixMovingNmeaDTOHandler, gpsFixNmeaDTOHandler));
}
}
@@ -1,5 +1,7 @@
package com.sap.sse.common;
import java.util.Set;
/**
* @author Fredrik Teschke
@@ -16,6 +18,8 @@ public interface TypeBasedServiceFinder<ServiceType> {
* @throws NoCorrespondingServiceRegisteredException Thrown, if no service is registered for this type.
*/
ServiceType findService(String type) throws NoCorrespondingServiceRegisteredException;
Set<ServiceType> findAllServices();
/**
* Sets a fallback service (optional), that is used if no service is registered for a {@code type}.
@@ -1,5 +1,8 @@
package com.sap.sse.common.impl;
import java.util.Collections;
import java.util.Set;
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
import com.sap.sse.common.TypeBasedServiceFinder;
@@ -36,5 +39,9 @@ TypeBasedServiceFinder<ServiceType> {
public void setFallbackService(ServiceType fallback) {
this.fallback = fallback;
}
@Override
public Set<ServiceType> findAllServices() {
return Collections.singleton(service);
}
}
@@ -6,12 +6,14 @@ Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: SAP
Bundle-Activator: com.sap.sse.filestorage.ui.server.Activator
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Import-Package: org.osgi.framework;version="1.3.0"
Import-Package: org.osgi.framework;version="1.3.0",
org.osgi.util.tracker;version="1.5.1"
Bundle-ActivationPolicy: lazy
Bundle-ClassPath: WEB-INF/classes/
Require-Bundle: javax.servlet;bundle-version="2.5.0",
com.sap.sse.gwt,
com.google.gwt.osgi;bundle-version="2.6.1",
com.sap.sse.filestorage,
com.sap.sse.common;bundle-version="1.0.0"
com.sap.sse.common;bundle-version="1.0.0",
com.sap.sse.osgi;bundle-version="1.0.0"
Web-ContextPath: /filestorage/ui
@@ -1,20 +0,0 @@
package com.sap.sse.filestorage.ui.client;
import org.osgi.framework.InvalidSyntaxException;
import com.google.gwt.user.client.rpc.RemoteService;
import com.sap.sse.filestorage.InvalidPropertiesException;
import com.sap.sse.filestorage.ui.shared.FileStorageServiceDTO;
/**
* For use with GWT for managing the file storage service to use.
* @author Fredrik Teschke
*
*/
public interface FileStorageManagementService extends RemoteService {
FileStorageServiceDTO[] getAvailableFileStorageServices() throws InvalidSyntaxException;
void setFileStorageServiceProperty(String serviceName, String propertyName, String propertyValue);
void testFileStorageServiceProperties(String serviceName) throws InvalidPropertiesException;
void setFileStorageServiceToUse(String serviceName) throws InvalidPropertiesException;
}
@@ -0,0 +1,42 @@
package com.sap.sse.filestorage.ui.client;
import com.google.gwt.user.client.rpc.RemoteService;
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
import com.sap.sse.filestorage.InvalidPropertiesException;
import com.sap.sse.filestorage.ui.shared.FileStorageServiceDTO;
/**
* For use with GWT for managing the file storage service to use.
*
* @author Fredrik Teschke
*
*/
public interface FileStorageRpcManagementService extends RemoteService {
FileStorageServiceDTO[] getAvailableFileStorageServices();
/**
* @throws NoCorrespondingServiceRegisteredException service may have disappeared from registry in the meantime
* @throws IllegalArgumentException if the property with name {@code propertyName} doesn't exist for the service
*/
void setFileStorageServiceProperty(String serviceName, String propertyName, String propertyValue)
throws NoCorrespondingServiceRegisteredException, IllegalArgumentException;
/**
* @throws NoCorrespondingServiceRegisteredException service may have disappeared from registry in the meantime
* @throws InvalidPropertiesException is thrown if properties are not valid
*/
void testFileStorageServiceProperties(String serviceName) throws NoCorrespondingServiceRegisteredException,
InvalidPropertiesException;
/**
* @throws NoCorrespondingServiceRegisteredException service may have disappeared from registry in the meantime
* @throws InvalidPropertiesException only a service with valid properties can be selected for usage
*/
void setActiveFileStorageService(String serviceName) throws NoCorrespondingServiceRegisteredException,
InvalidPropertiesException;
/**
* @return may be {@code null}
*/
String getActiveFileStorageServiceName();
}
@@ -3,15 +3,17 @@ package com.sap.sse.filestorage.ui.client;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sap.sse.filestorage.ui.shared.FileStorageServiceDTO;
public interface FileStorageManagementServiceAsync {
public interface FileStorageRpcManagementServiceAsync {
void getAvailableFileStorageServices(AsyncCallback<FileStorageServiceDTO[]> callback);
void setFileStorageServiceProperty(String serviceName, String propertyName, String propertyValue,
AsyncCallback<Void> callback);
void setFileStorageServiceToUse(String serviceName, AsyncCallback<Void> callback);
void setActiveFileStorageService(String serviceName, AsyncCallback<Void> callback);
void testFileStorageServiceProperties(String serviceName, AsyncCallback<Void> callback);
void getActiveFileStorageServiceName(AsyncCallback<String> callback);
}
@@ -1,51 +0,0 @@
package com.sap.sse.filestorage.ui.server;
import java.util.ArrayList;
import java.util.List;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import com.sap.sse.filestorage.FileStorageService;
import com.sap.sse.filestorage.InvalidPropertiesException;
import com.sap.sse.filestorage.ui.client.FileStorageManagementService;
import com.sap.sse.filestorage.ui.shared.FileStorageServiceDTO;
public class FileStorageManagementServiceImpl implements FileStorageManagementService {
private final BundleContext context;
public FileStorageManagementServiceImpl() {
this.context = Activator.getContext();
}
@Override
public FileStorageServiceDTO[] getAvailableFileStorageServices() throws InvalidSyntaxException {
List<FileStorageServiceDTO> serviceDtos = new ArrayList<>();
for (ServiceReference<FileStorageService> ref : context.getServiceReferences(FileStorageService.class, null)) {
FileStorageService service = context.getService(ref);
serviceDtos.add(FileStorageServiceDTO.convert(service));
context.ungetService(ref);
}
return serviceDtos.toArray(new FileStorageServiceDTO[0]);
}
@Override
public void setFileStorageServiceProperty(String serviceName, String propertyName, String propertyValue) {
// TODO Auto-generated method stub
}
@Override
public void testFileStorageServiceProperties(String serviceName) throws InvalidPropertiesException {
// TODO Auto-generated method stub
}
@Override
public void setFileStorageServiceToUse(String serviceName) throws InvalidPropertiesException {
// TODO Auto-generated method stub
}
}
@@ -0,0 +1,56 @@
package com.sap.sse.filestorage.ui.server;
import java.util.ArrayList;
import java.util.List;
import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;
import com.sap.sse.filestorage.FileStorageManagementService;
import com.sap.sse.filestorage.FileStorageService;
import com.sap.sse.filestorage.InvalidPropertiesException;
import com.sap.sse.filestorage.ui.client.FileStorageRpcManagementService;
import com.sap.sse.filestorage.ui.shared.FileStorageServiceDTO;
public class FileStorageRpcManagementServiceImpl implements FileStorageRpcManagementService {
private final ServiceTracker<FileStorageManagementService, FileStorageManagementService> managementServiceTracker;
public FileStorageRpcManagementServiceImpl() {
BundleContext context = Activator.getContext();
managementServiceTracker = new ServiceTracker<>(context, FileStorageManagementService.class.getName(), null);
managementServiceTracker.open();
}
private FileStorageManagementService getManagementService() {
return managementServiceTracker.getService();
}
@Override
public FileStorageServiceDTO[] getAvailableFileStorageServices() {
List<FileStorageServiceDTO> serviceDtos = new ArrayList<>();
for (FileStorageService s : getManagementService().getAvailableFileStorageServices()) {
serviceDtos.add(FileStorageServiceDTO.convert(s));
}
return serviceDtos.toArray(new FileStorageServiceDTO[0]);
}
@Override
public void setFileStorageServiceProperty(String serviceName, String propertyName, String propertyValue) {
getManagementService().setFileStorageServiceProperty(serviceName, propertyName, propertyValue);
}
@Override
public void testFileStorageServiceProperties(String serviceName) throws InvalidPropertiesException {
getManagementService().getFileStorageService(serviceName).testProperties();
}
@Override
public void setActiveFileStorageService(String serviceName) throws InvalidPropertiesException {
getManagementService().setActiveFileStorageService(getManagementService().getFileStorageService(serviceName));
}
@Override
public String getActiveFileStorageServiceName() {
return getManagementService().getActiveFileStorageService().getName();
}
}
@@ -8,7 +8,8 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Export-Package: com.sap.sse.filestorage,
com.sap.sse.filestorage.impl,
com.sap.sse.filestorage.testsupport
Import-Package: org.osgi.framework;version="1.8.0"
Import-Package: com.sap.sse.osgi,
org.osgi.framework;version="1.8.0"
Bundle-Activator: com.sap.sse.filestorage.impl.Activator
Require-Bundle: org.apache.servicemix.bundles.aws-java-sdk;bundle-version="1.9.8",
com.fasterxml.jackson.core.jackson-databind,
@@ -0,0 +1,36 @@
package com.sap.sse.filestorage;
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
/**
* OSGi service for managing {@link FileStorageService FileStorageServices}.
*
* @author Fredrik Teschke
*
*/
public interface FileStorageManagementService {
FileStorageService[] getAvailableFileStorageServices();
FileStorageService getFileStorageService(String name);
/**
* Sets the property of the service, and also stores the property value so that it can be restored
* after a server restart.
* @throws NoCorrespondingServiceRegisteredException service may have disappeared from registry in the meantime
* @throws IllegalArgumentException if the property with name {@code propertyName} doesn't exist for the service
*/
void setFileStorageServiceProperty(String serviceName, String propertyName, String propertyValue)
throws NoCorrespondingServiceRegisteredException, IllegalArgumentException;
/**
* @return may be {@code null} if no service has been selected so far.
*/
FileStorageService getActiveFileStorageService();
/**
* @throws InvalidPropertiesException
* if the service properties are {@link FileStorageService#testProperties() invalid}. Then the old
* active service (if any) remains active.
*/
void setActiveFileStorageService(FileStorageService service) throws InvalidPropertiesException;
}
@@ -4,11 +4,13 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import com.sap.sse.common.TypeBasedServiceFinder;
/**
* Service for storing files. The interface is intentionally agnostic of the underlying implementation, which may be
* provided e.g. by using Amazon's S3 or simply saving the files to a statically reachable directory on one of our
* servers. Implementations of this service are announced via the OSGi service registry. They should provide their name
* as the OSGi property "name";
* as the OSGi property {@link TypeBasedServiceFinder#TYPE type};
*
* TODO The storage service to use should be configured via the AdminConsole. Upon auto-discovering the available
* services, the AdminConsole should allow to edit properties for each service (e.g. access credentials for AWS S3). We
@@ -34,6 +36,8 @@ public interface FileStorageService {
Property[] getProperties();
/**
* Should not be called directly, but through {@link FileStorageManagementService#setFileStorageServiceProperty}
* as this deals with storing the new values.
* @throws IllegalArgumentException
* if {@code name} is not a valid property name
*/
@@ -1,15 +1,30 @@
package com.sap.sse.filestorage.impl;
import java.util.Dictionary;
import java.util.Hashtable;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import com.sap.sse.common.TypeBasedServiceFinder;
import com.sap.sse.filestorage.FileStorageManagementService;
import com.sap.sse.filestorage.FileStorageService;
public class Activator implements BundleActivator {
@Override
public void start(BundleContext context) throws Exception {
context.registerService(FileStorageService.class, new AmazonS3FileStorageServiceImpl(), null);
Dictionary<String, String> dict = new Hashtable<>();
dict.put(TypeBasedServiceFinder.TYPE, AmazonS3FileStorageServiceImpl.NAME);
context.registerService(FileStorageService.class, new AmazonS3FileStorageServiceImpl(), dict);
TransientFileStorageManagementServiceImpl mgmtService = new TransientFileStorageManagementServiceImpl();
context.registerService(FileStorageManagementService.class, mgmtService,
null);
mgmtService.setContext(context);
//TODO load service properties from DB on startup
}
@Override
@@ -35,6 +35,7 @@ import com.sap.sse.filestorage.Property;
*
*/
public class AmazonS3FileStorageServiceImpl implements FileStorageService {
public static final String NAME = "Amazon S3";
private static final Logger logger = Logger.getLogger(AmazonS3FileStorageServiceImpl.class.getName());
private static final String baseUrl = "s3.amazonaws.com";
@@ -144,7 +145,7 @@ public class AmazonS3FileStorageServiceImpl implements FileStorageService {
@Override
public String getName() {
return "Amazon S3";
return NAME;
}
@Override
@@ -0,0 +1,48 @@
package com.sap.sse.filestorage.impl;
import org.osgi.framework.BundleContext;
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
import com.sap.sse.common.TypeBasedServiceFinder;
import com.sap.sse.filestorage.FileStorageManagementService;
import com.sap.sse.filestorage.FileStorageService;
import com.sap.sse.filestorage.InvalidPropertiesException;
import com.sap.sse.osgi.CachedOsgiTypeBasedServiceFinderFactory;
public class TransientFileStorageManagementServiceImpl implements FileStorageManagementService {
private FileStorageService active;
private TypeBasedServiceFinder<FileStorageService> serviceFinder;
public void setContext(BundleContext context) {
serviceFinder = new CachedOsgiTypeBasedServiceFinderFactory(context)
.createServiceFinder(FileStorageService.class);
}
@Override
public FileStorageService getActiveFileStorageService() {
return active;
}
@Override
public void setActiveFileStorageService(FileStorageService service) throws InvalidPropertiesException {
active = service;
}
@Override
public FileStorageService[] getAvailableFileStorageServices() {
return serviceFinder.findAllServices().toArray(new FileStorageService[0]);
}
@Override
public FileStorageService getFileStorageService(String name) {
return serviceFinder.findService(name);
}
@Override
public void setFileStorageServiceProperty(String serviceName, String propertyName, String propertyValue)
throws NoCorrespondingServiceRegisteredException, IllegalArgumentException {
//TODO mgmt service that persists properties on master
serviceFinder.findService(serviceName).setProperty(propertyName, propertyValue);
}
}
@@ -1,7 +1,9 @@
package com.sap.sse.osgi;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
@@ -71,4 +73,9 @@ public class CachedOsgiTypeBasedServiceFinder<ServiceT> implements ServiceTracke
public void setFallbackService(ServiceT fallback) {
this.fallback = fallback;
}
@Override
public Set<ServiceT> findAllServices() {
return new HashSet<ServiceT>(services.values());
}
}