Skip to content

Commit

Permalink
Fixed NPE on Service update
Browse files Browse the repository at this point in the history
  • Loading branch information
smithkm authored and jodygarnett committed Jan 15, 2015
1 parent e1864b0 commit 270de80
Show file tree
Hide file tree
Showing 8 changed files with 277 additions and 33 deletions.
7 changes: 7 additions & 0 deletions pom.xml
Expand Up @@ -93,6 +93,13 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.geoserver</groupId>
<artifactId>wms</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>

</dependencies>


Expand Down
42 changes: 16 additions & 26 deletions src/main/java/org/geoserver/cluster/ConfigChangeEvent.java
Expand Up @@ -3,36 +3,28 @@
import java.util.HashMap;
import java.util.Map;

import org.geoserver.catalog.AttributeTypeInfo;
import org.geoserver.catalog.AttributionInfo;
import org.geoserver.catalog.AuthorityURLInfo;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.CoverageDimensionInfo;
import org.geoserver.catalog.CoverageInfo;
import org.geoserver.catalog.CoverageStoreInfo;
import org.geoserver.catalog.DataStoreInfo;
import org.geoserver.catalog.FeatureTypeInfo;
import org.geoserver.catalog.Info;
import org.geoserver.catalog.LayerGroupInfo;
import org.geoserver.catalog.LayerIdentifierInfo;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.MetadataLinkInfo;
import org.geoserver.catalog.NamespaceInfo;
import org.geoserver.catalog.StyleInfo;
import org.geoserver.catalog.WMSLayerInfo;
import org.geoserver.catalog.WMSStoreInfo;
import org.geoserver.catalog.WorkspaceInfo;
import org.geoserver.catalog.impl.AttributeTypeInfoImpl;
import org.geoserver.catalog.impl.AttributionInfoImpl;
import org.geoserver.catalog.impl.AuthorityURL;
import org.geoserver.catalog.impl.CatalogImpl;
import org.geoserver.catalog.impl.CoverageDimensionImpl;
import org.geoserver.catalog.impl.CoverageInfoImpl;
import org.geoserver.catalog.impl.CoverageStoreInfoImpl;
import org.geoserver.catalog.impl.DataStoreInfoImpl;
import org.geoserver.catalog.impl.FeatureTypeInfoImpl;
import org.geoserver.catalog.impl.LayerGroupInfoImpl;
import org.geoserver.catalog.impl.LayerIdentifier;
import org.geoserver.catalog.impl.LayerInfoImpl;
import org.geoserver.catalog.impl.MetadataLinkInfoImpl;
import org.geoserver.catalog.impl.NamespaceInfoImpl;
Expand All @@ -41,15 +33,12 @@
import org.geoserver.catalog.impl.WMSStoreInfoImpl;
import org.geoserver.catalog.impl.WorkspaceInfoImpl;
import org.geoserver.config.ContactInfo;
import org.geoserver.config.CoverageAccessInfo;
import org.geoserver.config.GeoServerInfo;
import org.geoserver.config.JAIInfo;
import org.geoserver.config.LoggingInfo;
import org.geoserver.config.ServiceInfo;
import org.geoserver.config.SettingsInfo;
import org.geoserver.config.impl.ContactInfoImpl;
import org.geoserver.config.impl.CoverageAccessInfoImpl;
import org.geoserver.config.impl.GeoServerInfoImpl;
import org.geoserver.config.impl.JAIInfoImpl;
import org.geoserver.config.impl.LoggingInfoImpl;
import org.geoserver.config.impl.SettingsInfoImpl;

Expand All @@ -58,15 +47,13 @@
* @author Justin Deoliveira, OpenGeo
*
*/
public class ConfigChangeEvent<T extends Info> extends Event {
public class ConfigChangeEvent extends Event {

static Map<Class,Class> INTERFACES = new HashMap<Class,Class>();
static Map<Class<? extends Info>,Class<? extends Info>> INTERFACES = new HashMap<Class<? extends Info>,Class<? extends Info>>();
static {
INTERFACES.put(GeoServerInfoImpl.class, GeoServerInfo.class);
INTERFACES.put(SettingsInfoImpl.class, SettingsInfo.class);
INTERFACES.put(LoggingInfoImpl.class, LoggingInfo.class);
INTERFACES.put(JAIInfoImpl.class, JAIInfo.class);
INTERFACES.put(CoverageAccessInfoImpl.class, CoverageAccessInfo.class);
INTERFACES.put(ContactInfoImpl.class, ContactInfo.class);
INTERFACES.put(AttributionInfoImpl.class, AttributionInfo.class);

Expand All @@ -81,13 +68,10 @@ public class ConfigChangeEvent<T extends Info> extends Event {
INTERFACES.put(FeatureTypeInfoImpl.class, FeatureTypeInfo.class );
INTERFACES.put(CoverageInfoImpl.class, CoverageInfo.class);
INTERFACES.put(WMSLayerInfoImpl.class, WMSLayerInfo.class);
INTERFACES.put(CoverageDimensionImpl.class, CoverageDimensionInfo.class);
INTERFACES.put(MetadataLinkInfoImpl.class, MetadataLinkInfo.class);
INTERFACES.put(AttributeTypeInfoImpl.class, AttributeTypeInfo.class );
INTERFACES.put(LayerInfoImpl.class, LayerInfo.class);
INTERFACES.put(LayerGroupInfoImpl.class, LayerGroupInfo.class );
INTERFACES.put(LayerIdentifier.class, LayerIdentifierInfo.class );
INTERFACES.put(AuthorityURL.class, AuthorityURLInfo.class );

}

/** serialVersionUID */
Expand Down Expand Up @@ -115,14 +99,14 @@ public enum Type {
/**
* class of object
*/
Class<T> clazz;
Class<? extends Info> clazz;

/**
* type of config change
*/
Type type;

public ConfigChangeEvent(String id, String name, Class<T> clazz, Type type) {
public ConfigChangeEvent(String id, String name, Class<? extends Info> clazz, Type type) {
this.id = id;
this.name = name;
this.clazz = clazz;
Expand All @@ -145,16 +129,22 @@ public void setWorkspaceId(String workspaceId) {
this.workspaceId = workspaceId;
}

public Class<T> getObjectClass() {
public Class<? extends Info> getObjectClass() {
return clazz;
}

public Class<T> getObjectInterface() {
Class clazz = INTERFACES.get(getObjectClass());
public Class<? extends Info> getObjectInterface() {
Class<? extends Info> clazz = INTERFACES.get(getObjectClass());

// There are several different ServiceInfo subtypes and it's an extension point
// so don't check for specific classes
if(clazz==null && ServiceInfo.class.isAssignableFrom(getObjectClass())){
clazz = ServiceInfo.class;
}

// Fall back, mostly here to support EasyMock test objects in unit tests.
if(clazz==null) {
for(Class realClazz: INTERFACES.values()) {
for(Class<? extends Info> realClazz: INTERFACES.values()) {
if(realClazz.isAssignableFrom(getObjectClass())) {
clazz=realClazz;
break;
Expand Down
Expand Up @@ -140,7 +140,7 @@ protected void dispatch(Event e) {
*/
protected abstract void processEventQueue(Queue<Event> q) throws Exception;

ConfigChangeEvent<?> newChangeEvent(CatalogEvent evt, Type type) {
ConfigChangeEvent newChangeEvent(CatalogEvent evt, Type type) {
return newChangeEvent(evt.getSource(), type);
}

Expand Down
Expand Up @@ -30,7 +30,7 @@ public class ConfigChangeEventMatcher extends EventMatcher {
*/
ConfigChangeEvent.Type type;

static public <T extends Info> ConfigChangeEvent<T> configChangeEvent(Object source, String id, String name,
static public <T extends Info> ConfigChangeEvent configChangeEvent(Object source, String id, String name,
String workspaceId, Class<T> clazz, Type type){
EasyMock.reportMatcher(new ConfigChangeEventMatcher(source, id, name, workspaceId, clazz, type));
return null;
Expand Down
Expand Up @@ -12,8 +12,12 @@
import org.geoserver.catalog.DataStoreInfo;
import org.geoserver.catalog.Info;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.WorkspaceInfo;
import org.geoserver.config.ConfigurationListener;
import org.geoserver.config.GeoServerInfo;
import org.geoserver.config.LoggingInfo;
import org.geoserver.config.ServiceInfo;
import org.geoserver.config.SettingsInfo;
import org.hamcrest.integration.EasyMock2Adapter;
import org.junit.Before;

Expand Down Expand Up @@ -118,4 +122,43 @@ protected void expectationTestTwoLayerChangeWithPause(LayerInfo layerInfo,
expect(getCatalog().getLayer(layerId) ).andReturn(layerInfo).anyTimes();
getCatalog().firePostModified((CatalogInfo)info(layerId)); expectLastCall().times(2);
}

@Override
protected void expectationTestWorkspaceAdd(WorkspaceInfo info,
String workspaceName, String workspaceId) throws Exception {
expect(getCatalog().getWorkspace(workspaceId) ).andReturn(info);
getCatalog().fireAdded((CatalogInfo)info(workspaceId)); expectLastCall();
}

@Override
protected void expectationTestChangeSettings(SettingsInfo info,
String settingsId, WorkspaceInfo wsInfo, String workspaceId) throws Exception {

// TODO: Expect this instead of mocking ConfigurationListener
//expect(getGeoServer().fireSettingsPostModified());

configListener.handleSettingsPostModified((SettingsInfo)info(settingsId));expectLastCall();
expect(getGeoServer().getListeners()).andReturn(Arrays.asList(configListener));
}

@Override
protected void expectationTestChangeLogging(LoggingInfo info,
String loggingId) throws Exception {
// TODO: Expect this instead of mocking ConfigurationListener
//expect(getGeoServer().fireLoggingPostModified());

configListener.handlePostLoggingChange((LoggingInfo)info(loggingId));expectLastCall();
expect(getGeoServer().getListeners()).andReturn(Arrays.asList(configListener));
}

@Override
protected void expectationTestChangeService(ServiceInfo info,
String serviceId) throws Exception {
// TODO: Expect this instead of mocking ConfigurationListener
//expect(getGeoServer().fireLoggingPostModified());
configListener.handlePostServiceChange((ServiceInfo)info(serviceId));expectLastCall();
expect(getGeoServer().getListeners()).andReturn(Arrays.asList(configListener));

}

}
Expand Up @@ -6,14 +6,23 @@

import org.geoserver.catalog.DataStoreInfo;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.wms.WMSInfo;
import org.geoserver.wms.WMSInfoImpl;
import org.geoserver.catalog.WorkspaceInfo;
import org.geoserver.catalog.impl.DataStoreInfoImpl;
import org.geoserver.catalog.impl.LayerInfoImpl;
import org.geoserver.catalog.impl.WorkspaceInfoImpl;
import org.geoserver.cluster.ConfigChangeEvent;
import org.geoserver.cluster.ConfigChangeEvent.Type;
import org.geoserver.cluster.Event;
import org.geoserver.config.GeoServerInfo;
import org.geoserver.config.LoggingInfo;
import org.geoserver.config.ServiceInfo;
import org.geoserver.config.SettingsInfo;
import org.geoserver.config.impl.GeoServerInfoImpl;
import org.geoserver.config.impl.LoggingInfoImpl;
import org.geoserver.config.impl.SettingsInfoImpl;
import org.hamcrest.Matchers;
import org.junit.Test;

import com.hazelcast.core.Message;
Expand Down Expand Up @@ -300,7 +309,38 @@ public void testTwoLayerChangeWithPause() throws Exception {
}
verify(layerInfo);
}


@Test
public void testWorkspaceAdd() throws Exception {
WorkspaceInfo info;
final String workspaceName = "testStore";
final String workspaceId = "Store-TEST";

{
info = createMock(WorkspaceInfo.class);

expect(info.getName()).andStubReturn(workspaceName);
expect(info.getId()).andStubReturn(workspaceId);

expectationTestWorkspaceAdd(info, workspaceName, workspaceId);
}
replay(info);
{
HzSynchronizer sync = getSynchronizer();
sync.initialize(configWatcher);
ConfigChangeEvent evt = new ConfigChangeEvent(workspaceId, workspaceName, WorkspaceInfoImpl.class, Type.ADD);

// Mock a message coming in from the cluster

mockMessage(evt);
}
waitForSync();
verify(info);
}

protected abstract void expectationTestWorkspaceAdd(WorkspaceInfo info,
String workspaceName, String workspaceId) throws Exception;

protected void mockMessage(ConfigChangeEvent evt) {
evt.setSource(remoteAddress);
Message<Event> msg = new Message<Event>(TOPIC_NAME, evt);
Expand All @@ -309,4 +349,103 @@ protected void mockMessage(ConfigChangeEvent evt) {
}
}

@Test
public void testChangeSettings() throws Exception {
SettingsInfo info;
WorkspaceInfo wsInfo;
final String settingsId = "Settings-TEST";
final String workspaceId = "Workspace-TEST";

{
info = createMock(SettingsInfo.class);
wsInfo = createMock(WorkspaceInfo.class);

expect(wsInfo.getId()).andStubReturn(workspaceId);

expect(info.getWorkspace()).andStubReturn(wsInfo);
expect(getCatalog().getWorkspace(workspaceId)).andStubReturn(wsInfo);

expect(info.getId()).andStubReturn(settingsId);

expect(getGeoServer().getSettings(wsInfo)).andStubReturn(info);

expectationTestChangeSettings(info, settingsId, wsInfo, workspaceId);
}
replay(info, wsInfo);
{
HzSynchronizer sync = getSynchronizer();
sync.initialize(configWatcher);
ConfigChangeEvent evt = new ConfigChangeEvent(settingsId, null, SettingsInfoImpl.class, Type.MODIFY);
evt.setWorkspaceId(workspaceId);

// Mock a message coming in from the cluster

mockMessage(evt);
}
waitForSync();
verify(info, wsInfo);
}

protected abstract void expectationTestChangeSettings(SettingsInfo info, String settingsId, WorkspaceInfo wsInfo, String workspaceId) throws Exception;

@Test
public void testChangeLogging() throws Exception {
LoggingInfo info;
final String settingsId = "Logging-TEST";

{
info = createMock(LoggingInfo.class);

expect(info.getId()).andStubReturn(settingsId);

expect(getGeoServer().getLogging()).andStubReturn(info);

expectationTestChangeLogging(info, settingsId);
}
replay(info);
{
HzSynchronizer sync = getSynchronizer();
sync.initialize(configWatcher);
ConfigChangeEvent evt = new ConfigChangeEvent(settingsId, null, LoggingInfoImpl.class, Type.MODIFY);

// Mock a message coming in from the cluster

mockMessage(evt);
}
waitForSync();
verify(info);
}
protected abstract void expectationTestChangeLogging(LoggingInfo info, String loggingId) throws Exception;

@Test
public void testChangeService() throws Exception {
WMSInfo info;
final String serviceId = "Service-TEST";

{
info = createMock(WMSInfo.class);

expect(info.getId()).andStubReturn(serviceId);

expect(getGeoServer().getService(serviceId, WMSInfo.class)).andStubReturn(info);
expect(getGeoServer().getService(serviceId, ServiceInfo.class)).andStubReturn(info);

expectationTestChangeService(info, serviceId);
}
replay(info);
{
HzSynchronizer sync = getSynchronizer();
sync.initialize(configWatcher);

ConfigChangeEvent evt = new ConfigChangeEvent(serviceId, null, WMSInfoImpl.class, Type.MODIFY);

// Mock a message coming in from the cluster

mockMessage(evt);
}
waitForSync();
verify(info);
}
protected abstract void expectationTestChangeService(ServiceInfo info, String serviceId) throws Exception;

}

0 comments on commit 270de80

Please sign in to comment.