Skip to content

Commit 7d7368f

Browse files
Fix #111: Add error/failure logging and centralize package configs (#113)
Logging: We want to to log errors and failures by default to prevent those problems from being swallowed up since they may contain important information about underlying issues. EPackageConfigurations: Centralize EPackageConfiguration management and apply it on the Java model server client to ensure proper setup. We also ensure that the ChangePackage is properly initialized on the client-side. We already use the RecordingModelResourceManager as default on the server so we need the ChangePackage to be initialized.
1 parent 3dd51b9 commit 7d7368f

8 files changed

Lines changed: 126 additions & 42 deletions

File tree

bundles/org.eclipse.emfcloud.modelserver.client/META-INF/MANIFEST.MF

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ Require-Bundle: com.fasterxml.jackson.core.jackson-core;bundle-version="[2.9.0,3
1414
org.eclipse.emfcloud.modelserver.common;bundle-version="[0.7.0,1.0.0)",
1515
org.eclipse.emfcloud.modelserver.edit;bundle-version="[0.7.0,1.0.0)",
1616
org.eclipse.emfcloud.modelserver.lib;bundle-version="[0.7.0,1.0.0)",
17-
org.eclipse.emfcloud.modelserver.emf;bundle-version="[0.7.0,1.0.0)"
17+
org.eclipse.emfcloud.modelserver.emf;bundle-version="[0.7.0,1.0.0)",
18+
org.eclipse.emf.ecore.change;bundle-version="[2.14.0,3.0.0)"
1819
Export-Package: org.eclipse.emfcloud.modelserver.client,
1920
org.eclipse.emfcloud.modelserver.internal.client;x-internal:=true
2021
Bundle-Vendor: EclipseSource

bundles/org.eclipse.emfcloud.modelserver.client/src/org/eclipse/emfcloud/modelserver/client/ModelServerClient.java

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@
3636
import org.eclipse.emfcloud.modelserver.common.codecs.XmiCodec;
3737
import org.eclipse.emfcloud.modelserver.emf.common.JsonResponseMember;
3838
import org.eclipse.emfcloud.modelserver.emf.common.JsonResponseType;
39+
import org.eclipse.emfcloud.modelserver.emf.configuration.ChangePackageConfiguration;
40+
import org.eclipse.emfcloud.modelserver.emf.configuration.CommandPackageConfiguration;
41+
import org.eclipse.emfcloud.modelserver.emf.configuration.EPackageConfiguration;
42+
import org.eclipse.emfcloud.modelserver.emf.configuration.EcorePackageConfiguration;
3943
import org.eclipse.emfcloud.modelserver.internal.client.EditingContextImpl;
4044
import org.eclipse.emfcloud.modelserver.jsonschema.Json;
4145
import org.jetbrains.annotations.NotNull;
@@ -64,20 +68,39 @@ public class ModelServerClient implements ModelServerClientApi<EObject>, ModelSe
6468
public static final String PATCH = "PATCH";
6569
public static final String POST = "POST";
6670

67-
private static Logger LOG = Logger.getLogger(ModelServerClient.class.getSimpleName());
71+
protected static Logger LOG = Logger.getLogger(ModelServerClient.class.getSimpleName());
6872

6973
protected final OkHttpClient client;
7074
protected final String baseUrl;
7175
protected final Map<String, WebSocket> openSockets = new LinkedHashMap<>();
7276
protected final Map<EditingContextImpl, WebSocket> openEditingSockets = new LinkedHashMap<>();
77+
protected final EPackageConfiguration[] configurations;
7378

74-
public ModelServerClient(final String baseUrl) throws MalformedURLException {
75-
this(new OkHttpClient(), baseUrl);
79+
public ModelServerClient(final String baseUrl, final EPackageConfiguration... configurations)
80+
throws MalformedURLException {
81+
this(new OkHttpClient(), baseUrl, configurations);
7682
}
7783

78-
public ModelServerClient(final OkHttpClient client, final String baseUrl) throws MalformedURLException {
84+
public ModelServerClient(final OkHttpClient client, final String baseUrl,
85+
final EPackageConfiguration... configurations) throws MalformedURLException {
7986
this.client = client;
8087
this.baseUrl = new URL(baseUrl).toString();
88+
this.configurations = configurations;
89+
this.init();
90+
}
91+
92+
protected void init() {
93+
initEPackages();
94+
}
95+
96+
private void initEPackages() {
97+
// default packages that should always be present
98+
EPackageConfiguration.setup(
99+
new EcorePackageConfiguration(),
100+
new CommandPackageConfiguration(),
101+
new ChangePackageConfiguration());
102+
// custom packages adding or overriding default configurations
103+
EPackageConfiguration.setup(this.configurations);
81104
}
82105

83106
@Override

bundles/org.eclipse.emfcloud.modelserver.client/src/org/eclipse/emfcloud/modelserver/client/TypedSubscriptionListener.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@
1313
import java.util.Optional;
1414
import java.util.function.Function;
1515

16+
import org.apache.log4j.Logger;
1617
import org.eclipse.emfcloud.modelserver.emf.common.JsonResponseType;
1718

1819
public class TypedSubscriptionListener<T> implements NotificationSubscriptionListener<T> {
20+
private static Logger LOG = Logger.getLogger(TypedSubscriptionListener.class.getSimpleName());
21+
1922
private final Function<? super String, Optional<T>> updateFunction;
2023

2124
public TypedSubscriptionListener(final Function<String, Optional<T>> updateFunction) {
@@ -55,7 +58,9 @@ public void onNotification(final ModelServerNotification notification) {
5558
public void onSuccess(final Optional<String> message) {}
5659

5760
@Override
58-
public void onError(final Optional<String> message) {}
61+
public void onError(final Optional<String> message) {
62+
LOG.error("Error: " + message.orElse("Unknown"));
63+
}
5964

6065
@Override
6166
public void onDirtyChange(final boolean isDirty) {}
@@ -67,7 +72,9 @@ public void onFullUpdate(final T fullUpdate) {}
6772
public void onIncrementalUpdate(final T incrementalUpdate) {}
6873

6974
@Override
70-
public void onUnknown(final ModelServerNotification notification) {}
75+
public void onUnknown(final ModelServerNotification notification) {
76+
LOG.warn("Unknown notification type: " + notification.getType());
77+
}
7178

7279
@Override
7380
public void onOpen(final Response<String> response) {}
@@ -79,8 +86,12 @@ public void onClosing(final int code, final String reason) {}
7986
public void onClosed(final int code, final String reason) {}
8087

8188
@Override
82-
public void onFailure(final Throwable t, final Response<String> response) {}
89+
public void onFailure(final Throwable throwable, final Response<String> response) {
90+
LOG.error("Failure: " + response.getMessage(), throwable);
91+
}
8392

8493
@Override
85-
public void onFailure(final Throwable t) {}
94+
public void onFailure(final Throwable throwable) {
95+
LOG.error("Failure: ", throwable);
96+
}
8697
}

bundles/org.eclipse.emfcloud.modelserver.emf/src/org/eclipse/emfcloud/modelserver/emf/common/DefaultModelResourceManager.java

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -29,23 +29,21 @@
2929
import org.eclipse.emf.ecore.resource.ResourceSet;
3030
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
3131
import org.eclipse.emf.ecore.util.EcoreUtil;
32-
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
3332
import org.eclipse.emfcloud.modelserver.command.CCommand;
3433
import org.eclipse.emfcloud.modelserver.command.CCommandExecutionResult;
3534
import org.eclipse.emfcloud.modelserver.command.CCommandFactory;
3635
import org.eclipse.emfcloud.modelserver.common.codecs.DecodingException;
37-
import org.eclipse.emfcloud.modelserver.common.codecs.EMFJsonConverter;
3836
import org.eclipse.emfcloud.modelserver.common.codecs.EncodingException;
3937
import org.eclipse.emfcloud.modelserver.edit.CommandCodec;
4038
import org.eclipse.emfcloud.modelserver.edit.CommandExecutionType;
4139
import org.eclipse.emfcloud.modelserver.edit.ModelServerCommand;
4240
import org.eclipse.emfcloud.modelserver.edit.command.UpdateModelCommandContribution;
4341
import org.eclipse.emfcloud.modelserver.emf.configuration.EPackageConfiguration;
4442
import org.eclipse.emfcloud.modelserver.emf.configuration.ServerConfiguration;
45-
import org.emfjson.jackson.resource.JsonResourceFactory;
4643

4744
import com.google.common.base.Strings;
4845
import com.google.common.collect.Maps;
46+
import com.google.common.collect.Sets;
4947
import com.google.inject.Inject;
5048

5149
public class DefaultModelResourceManager implements ModelResourceManager {
@@ -66,16 +64,15 @@ public class DefaultModelResourceManager implements ModelResourceManager {
6664
public DefaultModelResourceManager(final Set<EPackageConfiguration> configurations,
6765
final AdapterFactory adapterFactory, final ServerConfiguration serverConfiguration) {
6866

69-
this.configurations = configurations;
67+
this.configurations = Sets.newLinkedHashSet(configurations);
7068
this.adapterFactory = adapterFactory;
7169
this.serverConfiguration = serverConfiguration;
7270
initialize();
7371
}
7472

7573
@Override
7674
public void initialize() {
77-
registerExtensions(configurations);
78-
configurations.forEach(EPackageConfiguration::registerEPackage);
75+
EPackageConfiguration.setup(configurations.toArray(EPackageConfiguration[]::new));
7976

8077
String workspacePath = this.serverConfiguration.getWorkspaceRootURI().toFileString();
8178
if (workspacePath != null) {
@@ -87,24 +84,6 @@ public void initialize() {
8784
}
8885
}
8986

90-
protected void registerExtensions(final Set<EPackageConfiguration> configurations) {
91-
Map<String, Object> map = Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap();
92-
// register default ResourceFactories (XMI and JSON)
93-
map.put("*", new XMIResourceFactoryImpl());
94-
map.put("json", new JsonResourceFactory(EMFJsonConverter.setupDefaultMapper()));
95-
// register additional ResourceFactories
96-
configurations.forEach(conf -> map.putAll(registerExtensions(conf)));
97-
}
98-
99-
protected Map<String, Object> registerExtensions(final EPackageConfiguration configuration) {
100-
Map<String, Object> map = Maps.newHashMap();
101-
configuration.getFileExtensions().forEach(ext -> {
102-
configuration.getResourceFactory(ext).ifPresent(fac -> map.put(ext, fac));
103-
});
104-
105-
return map;
106-
}
107-
10887
@Override
10988
public ResourceSet getResourceSet(final String modeluri) {
11089
return resourceSets.get(createURI(modeluri));

bundles/org.eclipse.emfcloud.modelserver.emf/src/org/eclipse/emfcloud/modelserver/emf/common/RecordingModelResourceManager.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.eclipse.emf.ecore.change.util.ChangeRecorder;
2020
import org.eclipse.emfcloud.modelserver.command.CCommand;
2121
import org.eclipse.emfcloud.modelserver.command.CCommandExecutionResult;
22+
import org.eclipse.emfcloud.modelserver.emf.configuration.ChangePackageConfiguration;
2223
import org.eclipse.emfcloud.modelserver.emf.configuration.EPackageConfiguration;
2324
import org.eclipse.emfcloud.modelserver.emf.configuration.ServerConfiguration;
2425

@@ -37,6 +38,12 @@ public RecordingModelResourceManager(final Set<EPackageConfiguration> configurat
3738
super(configurations, adapterFactory, serverConfiguration);
3839
}
3940

41+
@Override
42+
public void initialize() {
43+
this.configurations.add(new ChangePackageConfiguration());
44+
super.initialize();
45+
}
46+
4047
@Override
4148
protected CommandExecutionContext executeCommand(final ModelServerEditingDomain domain, final Command serverCommand,
4249
final CCommand clientCommand) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/********************************************************************************
2+
* Copyright (c) 2019 EclipseSource and others.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0 which is available at
6+
* https://www.eclipse.org/legal/epl-2.0, or the MIT License which is
7+
* available at https://opensource.org/licenses/MIT.
8+
*
9+
* SPDX-License-Identifier: EPL-2.0 OR MIT
10+
********************************************************************************/
11+
package org.eclipse.emfcloud.modelserver.emf.configuration;
12+
13+
import java.util.Collection;
14+
import java.util.Collections;
15+
16+
import org.eclipse.emf.ecore.change.ChangePackage;
17+
18+
public class ChangePackageConfiguration implements EPackageConfiguration {
19+
20+
@Override
21+
public Collection<String> getFileExtensions() { return Collections.emptyList(); }
22+
23+
@Override
24+
public void registerEPackage() {
25+
ChangePackage.eINSTANCE.eClass();
26+
}
27+
28+
@Override
29+
public String getId() { return ChangePackage.eNS_URI; }
30+
31+
}

bundles/org.eclipse.emfcloud.modelserver.emf/src/org/eclipse/emfcloud/modelserver/emf/configuration/EPackageConfiguration.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,15 @@
1010
********************************************************************************/
1111
package org.eclipse.emfcloud.modelserver.emf.configuration;
1212

13+
import java.util.Arrays;
1314
import java.util.Collection;
15+
import java.util.Map;
1416
import java.util.Optional;
1517

1618
import org.eclipse.emf.ecore.resource.Resource;
19+
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
20+
import org.eclipse.emfcloud.modelserver.common.codecs.EMFJsonConverter;
21+
import org.emfjson.jackson.resource.JsonResourceFactory;
1722

1823
public interface EPackageConfiguration {
1924
/**
@@ -48,4 +53,36 @@ public interface EPackageConfiguration {
4853
default Optional<Resource.Factory> getResourceFactory(final String extension) {
4954
return Optional.empty();
5055
}
56+
57+
default void registerFileExtensions() {
58+
registerFileExtensions(Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap());
59+
}
60+
61+
default void registerFileExtensions(final Map<String, Object> extensionToFactoryMap) {
62+
getFileExtensions().forEach(fileExtension -> {
63+
getResourceFactory(fileExtension).ifPresent(factory -> extensionToFactoryMap.put(fileExtension, factory));
64+
});
65+
}
66+
67+
default void register() {
68+
register(Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap());
69+
}
70+
71+
default void register(final Map<String, Object> extensionToFactoryMap) {
72+
registerEPackage();
73+
registerFileExtensions(extensionToFactoryMap);
74+
}
75+
76+
static void setup(final EPackageConfiguration... configurations) {
77+
setup(Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap(), configurations);
78+
}
79+
80+
static void setup(final Map<String, Object> extensionToFactoryMap, final EPackageConfiguration... configurations) {
81+
// default initialization as XMI resources
82+
extensionToFactoryMap.put("*", new XMIResourceFactoryImpl());
83+
// default json mapping
84+
extensionToFactoryMap.put("json", new JsonResourceFactory(EMFJsonConverter.setupDefaultMapper()));
85+
// custom configurations: may add or override default configurations (order matters)
86+
Arrays.stream(configurations).forEach(configuration -> configuration.register(extensionToFactoryMap));
87+
}
5188
}

examples/org.eclipse.emfcloud.modelserver.example/src/main/java/org/eclipse/emfcloud/modelserver/example/client/ExampleModelServerClient.java

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222
import org.eclipse.emfcloud.modelserver.client.SubscriptionListener;
2323
import org.eclipse.emfcloud.modelserver.coffee.model.coffee.CoffeePackage;
2424
import org.eclipse.emfcloud.modelserver.command.CCommand;
25-
import org.eclipse.emfcloud.modelserver.command.CCommandPackage;
2625
import org.eclipse.emfcloud.modelserver.edit.command.SetCommandContribution;
2726
import org.eclipse.emfcloud.modelserver.edit.util.CommandUtil;
27+
import org.eclipse.emfcloud.modelserver.example.CoffeePackageConfiguration;
2828
import org.eclipse.emfcloud.modelserver.example.UpdateTaskNameCommandContribution;
2929
import org.eclipse.emfcloud.modelserver.jsonschema.Json;
3030

@@ -48,8 +48,9 @@ public final class ExampleModelServerClient {
4848
private ExampleModelServerClient() {}
4949

5050
public static void main(final String[] args) {
51-
registerPackages();
52-
try (ModelServerClient client = new ModelServerClient("http://localhost:8081/api/v1/");
51+
try (
52+
ModelServerClient client = new ModelServerClient("http://localhost:8081/api/v1/",
53+
new CoffeePackageConfiguration());
5354
Scanner userInput = new Scanner(System.in)) {
5455
System.out.println("Simple Model Server Client Interface");
5556
System.out.println("====================================");
@@ -166,12 +167,6 @@ private static void handleUnsubscribe(final ModelServerClient client, final Stri
166167
System.out.println("< OK");
167168
}
168169

169-
private static void registerPackages() {
170-
EcorePackage.eINSTANCE.eClass();
171-
CCommandPackage.eINSTANCE.eClass();
172-
CoffeePackage.eINSTANCE.eClass();
173-
}
174-
175170
private static void printHelp() {
176171
System.out.println("Supported commands:");
177172
System.out.println("- " + CMD_SUBSCRIBE + " <modelUri> <format>");

0 commit comments

Comments
 (0)