Code Monkey home page Code Monkey logo

emfcloud-modelserver-theia's People

Contributors

agarciadom avatar camilleletavernier avatar cdamus avatar dependabot[bot] avatar eneufeld avatar lucas-koehler avatar martin-fleck-at avatar ndoschek avatar planger avatar sgraband avatar tortmayr avatar vhemery avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

emfcloud-modelserver-theia's Issues

Add a set of URI tests

Add a set of tests that test the variety of different URIs (e.g. containing relative hierarchies).
Use equals for comparisons (that ignores the order of query parameters for example) where applicable and provide a dedicated error message for a better test output for the developer.

Wrong subscription path calculation

Hi all!

I'm coming from here.

Basically I'm not able to subscribe to events from the Model Server. Taking a look to the requests in the Model Server side I was able to identify a wrong request to the subscribe method (localhost:8081/api/v1subscribe missing a '/').

Taking a look to the code of the v1 client I was able to see that the model-server-client.ts has the method createSubscriptionPath which does not explicitly insert the '/'. However, the model-server-client-v2.ts has the same method which actually inserts the missing '/' character.

Could perhaps someone take a look on it and verify if this is actually a bug?

Kind regards.

Update README

The auto-generated README file is outdated and needs to be updated to reflect the actual installation and startup process.

TheiaBackendModelServerClientV2.edit() does not work with CompoundCommand

TheiaModelServerClientV2.edit() worked if I set the SetCommand as an argument.
However, it didn't work if I included SetCommand in CompoundCommand and set CompoundCommand as an argument.

TheiaBackendModelServerClientV2.edit() is currently implemented as follows:

    edit(modeluri: URI, patchOrCommand: PatchOrCommand, format?: Format): Promise<ModelUpdateResult> {
        if (ModelServerCommand.is(patchOrCommand)) {
            return super.edit(modeluri, ensureCommandPrototype(patchOrCommand));
        }
        return super.edit(modeluri, patchOrCommand, format);
    }

The if clause should check for both command types (e.g. like if (ModelServerCommand.is(patchOrCommand) || CompoundCommand.is(patchOrCommand))).

( refs. eclipse-emfcloud/emfcloud#209 )

Migrate to prettier

Most of the EMF.cloud projects (including jsonForms and GLSP) are using a combination of prettier and eslint for linting and formatting.
This works pretty well and is more or less the de facto standard approach. However, the modelserver-theia project uses a custom formatting approach which is incompatible with prettier. In order to not break formatting prettier has to be explicitly disabled. We should unify this formatting settings and also migrate to prettier.

Update modelserver example jar

Currently we download the outdated standalone jar with version 0.0.1 from our previous repository com.eclipsesource.modelserver. If starting this project without an already running modelserver instance, the outdated version is started and most requests won't work as expected.

We need to make sure that the latest snapshot (currently 0.7.0-SNAPSHOT) from the correct sonatype repository is downloaded an started, if no other modelserver instance is running.

Commands in command-model.ts do not allow to set a monovalued containment reference

I'm trying to set a monovalued containment reference with a new value object.
For this purpose, I can not use the AddCommand, because the EMF AddCommand is not executable on a monovalued feature.

The SetCommand constructor let me choose between DataValueType[] (for attributes) and ModelServerReferenceDescription[] (existing objects, hence for non-containment references).

The only way I can make a correct command is by setting manually the objectsToAdd property.
But then, its the SetCommandContribution on the server which would not understand it. (by the way, the org.eclipse.emfcloud.modelserver.edit.command.SetCommandContribution.serverCommand(EditingDomain, CCommand) looks very weird to me, I don't think it handles all the cases, such as SetCommand used with a collection of values)

In the end, the simplest way is to create my own custom command contribution for the set...

Workspace root configuration not working in Windows

Hi,

I am no able to configure workspace when running theia in windows env with model server.

Issue -
I have a theia workspace at below path -
/d:/kuldeep/lab/theia-wksp
Theia client encode this url & send it to the model server backend as below for configuration -
/d%3A/kuldeep/lab/theia-wksp

DefaultUriHelper convert this to URI , which is causing the issue -

public static String withoutFileScheme(final String uriString) {
      URI uri = uriString.startsWith("file:") ? URI.createURI(uriString) : URI.createFileURI(uriString);
      return withoutFileScheme(uri).toString();
   }

This changes url to-
/d%253A/kuldeep/lab/theia-wksp

Due to this URL is not getting decoded correctly.

As a workaround, I have extended the DefaultUriHelper to override the below method-

         @Override
       public Optional<URI> toFileUri(String fileUrl) {
	// TODO Auto-generated method stub
	       try {
		return super.toFileUri(URLDecoder.decode(fileUrl, "UTF-8"));

	} catch (NullPointerException | IllegalArgumentException | UnsupportedEncodingException e) {
		LOG.warn(String.format("Could not convert to filePath! ’%s’ is not a valid URL", fileUrl));
		return Optional.empty();
	}
    }

Basically decoding the URL before converting it to URI.

Model validation results could use a Diagnostic interface

Currently, the model validation return the EMF Diagnostic as a plain JSON object.
In the code examples, this object is exploited only with
JSON.stringify(response.data)

It would be nice to expose the Typescript interface corresponding to org.eclipse.emf.common.util.Diagnostic (also named Diagnostic, but not the vscode one since Range does not make sense here...)
It would be even nicer to be able to log them in the Problems view with a new DiagnosticManager class extending the MarkerManager class from @theia/markers

In the end, logging validation results to the Problems view should be as simple as something like :

const validateResponse = await this.modelServer.validation(modelURI.toString());
const diagnostic = validateResponse.body as Diagnostic;
if(diagnostic.severity > Diagnostic.OK && !!diagnostic.children) {
  this.diagnosticManager.setMarkers(modelURI, diagnostic.children);
}

(I guess the owner second argument should be the model element, so maybe we would need an extra something to transform the model element to an owner string...)
The link with the editor would still be up to the implementer...

@sgraband can you confirm there is no work in progress on these aspects before I make a PR ?

Investigate issues on Windows for several requests in `v1`

Moved here from emfcloud-modelserver/issues/173

With current master and the latest Model Server version, the following workflow does not work under Windows:

  • Send edit request for Coffee.ecore to set ControlUnit name to ControlUnitNew
  • Send save request for Coffee.ecore
  • Changes are not reflected in the file
  • Send saveAll request for Coffee.ecore persists the changes

The edit request does succeed but the changes are not applied to the Coffee.ecore model.
A simple get request to fetch the model does not show the changed name.

The save request logs the following errors

Log excerpt
2022-04-05 11:33:03,381185600 [Thread-17] ERROR DefaultModelResourceManager - Could not load resource with URI: file:/c:/Users/user/Clients/OpenSource/emfcloud/emfcloud-modelserver-theia/examples/workspace/SuperBrewer3000.coffee
org.eclipse.emf.ecore.resource.impl.ResourceSetImpl$1DiagnosticWrappedException: org.xml.sax.SAXParseExceptionpublicId: file:/c:/Users/user/Clients/OpenSource/emfcloud/emfcloud-modelserver-theia/examples/workspace/SuperBrewer3000.coffee; systemId: file:/c:/Users/user/Clients/OpenSource/emfcloud/emfcloud-modelserver-theia/examples/workspace/SuperBrewer3000.coffee; lineNumber: 1; columnNumber: 1; Premature end of file.
	at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.handleDemandLoadException(ResourceSetImpl.java:319) ~[org.eclipse.emf.ecore_2.26.0.v20220123-0838.jar:?]
	at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.demandLoadHelper(ResourceSetImpl.java:278) ~[org.eclipse.emf.ecore_2.26.0.v20220123-0838.jar:?]
	at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.getResource(ResourceSetImpl.java:406) ~[org.eclipse.emf.ecore_2.26.0.v20220123-0838.jar:?]
	at org.eclipse.emfcloud.modelserver.emf.common.DefaultModelResourceManager.loadResource(DefaultModelResourceManager.java:323) ~[classes/:?]
	at org.eclipse.emfcloud.modelserver.emf.common.DefaultModelResourceManager.basicCloseResource(DefaultModelResourceManager.java:452) ~[classes/:?]
	at org.eclipse.emfcloud.modelserver.emf.common.DefaultModelResourceManager.closeResource(DefaultModelResourceManager.java:409) ~[classes/:?]
	at org.eclipse.emfcloud.modelserver.emf.common.DefaultModelRepository.closeModel(DefaultModelRepository.java:157) ~[classes/:?]
	at org.eclipse.emfcloud.modelserver.emf.common.watchers.ReconcilingStrategy$AlwaysReload.basicReconcileModel(ReconcilingStrategy.java:79) ~[classes/:?]
	at org.eclipse.emfcloud.modelserver.emf.common.watchers.ReconcilingStrategy$AlwaysReload.lambda$0(ReconcilingStrategy.java:64) ~[classes/:?]
	at org.eclipse.emfcloud.modelserver.emf.common.DefaultModelResourceManager.runResourceSetAction(DefaultModelResourceManager.java:780) [classes/:?]
	at org.eclipse.emfcloud.modelserver.emf.common.DefaultModelRepository.runResourceSetAction(DefaultModelRepository.java:206) [classes/:?]
	at org.eclipse.emfcloud.modelserver.emf.common.watchers.ReconcilingStrategy$AlwaysReload.reconcileModel(ReconcilingStrategy.java:63) [classes/:?]
	at org.eclipse.emfcloud.modelserver.emf.common.watchers.AbstractModelWatcher.reconcile(AbstractModelWatcher.java:52) [classes/:?]
	at org.eclipse.emfcloud.modelserver.emf.common.watchers.FileModelWatcher.handleEvent(FileModelWatcher.java:167) [classes/:?]
	at org.eclipse.emfcloud.modelserver.emf.common.watchers.FileModelWatcher.run(FileModelWatcher.java:129) [classes/:?]
	at java.lang.Thread.run(Thread.java:834) [?:?]
Caused by: org.xml.sax.SAXParseException: Premature end of file.
	at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:204) ~[?:?]
	at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:178) ~[?:?]
	at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:400) ~[?:?]
	at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:327) ~[?:?]
	at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1471) ~[?:?]
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:1013) ~[?:?]
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:605) ~[?:?]
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:534) ~[?:?]
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:888) ~[?:?]
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:824) ~[?:?]
	at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141) ~[?:?]
	at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1216) ~[?:?]
	at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:635) ~[?:?]
	at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.parse(SAXParserImpl.java:324) ~[?:?]
	at org.eclipse.emf.ecore.xmi.impl.XMLLoadImpl.load(XMLLoadImpl.java:175) ~[org.eclipse.emf.ecore.xmi_2.16.0.v20190528-0725.jar:?]
	at org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.doLoad(XMLResourceImpl.java:261) ~[org.eclipse.emf.ecore.xmi_2.16.0.v20190528-0725.jar:?]
	at org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(ResourceImpl.java:1563) ~[org.eclipse.emf.ecore_2.26.0.v20220123-0838.jar:?]
	at org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(ResourceImpl.java:1342) ~[org.eclipse.emf.ecore_2.26.0.v20220123-0838.jar:?]
	at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.demandLoad(ResourceSetImpl.java:259) ~[org.eclipse.emf.ecore_2.26.0.v20220123-0838.jar:?]
	at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.demandLoadHelper(ResourceSetImpl.java:274) ~[org.eclipse.emf.ecore_2.26.0.v20220123-0838.jar:?]
	... 14 more
2022-04-05 11:33:03,372234700 [JettyServerThreadPool-28] ERROR SingleThreadModelController - Execution Exception
java.util.concurrent.ExecutionException: java.lang.NullPointerException
	at java.util.concurrent.FutureTask.report(FutureTask.java:122) ~[?:?]
	at java.util.concurrent.FutureTask.get(FutureTask.java:205) ~[?:?]
	at org.eclipse.emfcloud.modelserver.emf.common.SingleThreadModelController.waitComplete(SingleThreadModelController.java:225) ~[classes/:?]
	at org.eclipse.emfcloud.modelserver.emf.common.SingleThreadModelController.runAndWait(SingleThreadModelController.java:219) ~[classes/:?]
	at org.eclipse.emfcloud.modelserver.emf.common.SingleThreadModelController.save(SingleThreadModelController.java:145) ~[classes/:?]
	at org.eclipse.emfcloud.modelserver.emf.common.ModelServerRoutingDelegate.lambda$10(ModelServerRoutingDelegate.java:163) ~[classes/:?]
	at java.util.Optional.ifPresentOrElse(Optional.java:201) ~[?:?]
	at org.eclipse.emfcloud.modelserver.emf.common.ModelURIConverter.withResolvedModelURI(ModelURIConverter.java:99) ~[classes/:?]
	at org.eclipse.emfcloud.modelserver.emf.common.ModelURIConverter.withResolvedModelURI(ModelURIConverter.java:153) ~[classes/:?]
	at org.eclipse.emfcloud.modelserver.emf.common.ModelServerRoutingDelegate.saveModel(ModelServerRoutingDelegate.java:163) ~[classes/:?]
	at io.javalin.core.security.SecurityUtil.noopAccessManager(SecurityUtil.kt:20) ~[javalin-4.3.0.jar:4.3.0]
	at io.javalin.http.JavalinServlet.addHandler$lambda-5(JavalinServlet.kt:115) ~[javalin-4.3.0.jar:4.3.0]
	at io.javalin.http.JavalinServlet$service$tryBeforeAndEndpointHandlers$1.invoke(JavalinServlet.kt:44) ~[javalin-4.3.0.jar:4.3.0]
	at io.javalin.http.JavalinServlet$service$tryBeforeAndEndpointHandlers$1.invoke(JavalinServlet.kt:39) ~[javalin-4.3.0.jar:4.3.0]
	at io.javalin.http.JavalinServlet.service$tryWithExceptionMapper(JavalinServlet.kt:131) ~[javalin-4.3.0.jar:4.3.0]
	at io.javalin.http.JavalinServlet.service$tryBeforeAndEndpointHandlers(JavalinServlet.kt:39) ~[javalin-4.3.0.jar:4.3.0]
	at io.javalin.http.JavalinServlet.service(JavalinServlet.kt:87) ~[javalin-4.3.0.jar:4.3.0]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:584) ~[jakarta.servlet-api_4.0.0.jar:4.0.4]
	at io.javalin.jetty.JavalinJettyServlet.service(JavalinJettyServlet.kt:58) ~[javalin-4.3.0.jar:4.3.0]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:584) ~[jakarta.servlet-api_4.0.0.jar:4.0.4]
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799) ~[org.eclipse.jetty.servlet_9.4.44.v20210927.jar:9.4.44.v20210927]
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:550) ~[org.eclipse.jetty.servlet_9.4.44.v20210927.jar:9.4.44.v20210927]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233) ~[org.eclipse.jetty.server_9.4.44.v20210927.jar:9.4.44.v20210927]
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624) ~[org.eclipse.jetty.server_9.4.44.v20210927.jar:9.4.44.v20210927]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233) ~[org.eclipse.jetty.server_9.4.44.v20210927.jar:9.4.44.v20210927]
	at io.javalin.jetty.JettyServer$start$wsAndHttpHandler$1.doHandle(JettyServer.kt:52) ~[javalin-4.3.0.jar:4.3.0]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188) ~[org.eclipse.jetty.server_9.4.44.v20210927.jar:9.4.44.v20210927]
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501) ~[org.eclipse.jetty.servlet_9.4.44.v20210927.jar:9.4.44.v20210927]
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594) ~[org.eclipse.jetty.server_9.4.44.v20210927.jar:9.4.44.v20210927]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186) ~[org.eclipse.jetty.server_9.4.44.v20210927.jar:9.4.44.v20210927]
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1349) ~[org.eclipse.jetty.server_9.4.44.v20210927.jar:9.4.44.v20210927]
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) ~[org.eclipse.jetty.server_9.4.44.v20210927.jar:9.4.44.v20210927]
	at org.eclipse.jetty.server.handler.StatisticsHandler.handle(StatisticsHandler.java:179) ~[org.eclipse.jetty.server_9.4.44.v20210927.jar:9.4.44.v20210927]
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[org.eclipse.jetty.server_9.4.44.v20210927.jar:9.4.44.v20210927]
	at org.eclipse.jetty.server.Server.handle(Server.java:516) ~[org.eclipse.jetty.server_9.4.44.v20210927.jar:9.4.44.v20210927]
	at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:400) ~[org.eclipse.jetty.server_9.4.44.v20210927.jar:9.4.44.v20210927]
	at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:645) [org.eclipse.jetty.server_9.4.44.v20210927.jar:9.4.44.v20210927]
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:392) [org.eclipse.jetty.server_9.4.44.v20210927.jar:9.4.44.v20210927]
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277) [org.eclipse.jetty.server_9.4.44.v20210927.jar:9.4.44.v20210927]
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311) [org.eclipse.jetty.io_9.4.44.v20210927.jar:9.4.44.v20210927]
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105) [org.eclipse.jetty.io_9.4.44.v20210927.jar:9.4.44.v20210927]
	at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104) [org.eclipse.jetty.io_9.4.44.v20210927.jar:9.4.44.v20210927]
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338) [org.eclipse.jetty.util_9.4.44.v20210927.jar:9.4.44.v20210927]
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315) [org.eclipse.jetty.util_9.4.44.v20210927.jar:9.4.44.v20210927]
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173) [org.eclipse.jetty.util_9.4.44.v20210927.jar:9.4.44.v20210927]
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131) [org.eclipse.jetty.util_9.4.44.v20210927.jar:9.4.44.v20210927]
	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:409) [org.eclipse.jetty.util_9.4.44.v20210927.jar:9.4.44.v20210927]
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883) [org.eclipse.jetty.util_9.4.44.v20210927.jar:9.4.44.v20210927]
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034) [org.eclipse.jetty.util_9.4.44.v20210927.jar:9.4.44.v20210927]
	at java.lang.Thread.run(Thread.java:834) [?:?]
Caused by: java.lang.NullPointerException
	at org.eclipse.emfcloud.modelserver.emf.common.DefaultModelResourceManager.save(DefaultModelResourceManager.java:706) ~[classes/:?]
	at org.eclipse.emfcloud.modelserver.emf.common.DefaultModelRepository.saveModel(DefaultModelRepository.java:162) ~[classes/:?]
	at org.eclipse.emfcloud.modelserver.emf.common.DefaultModelController.save(DefaultModelController.java:229) ~[classes/:?]
	at org.eclipse.emfcloud.modelserver.emf.common.SingleThreadModelController.lambda$9(SingleThreadModelController.java:145) ~[classes/:?]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) ~[?:?]
	at java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[?:?]
	at org.eclipse.emfcloud.modelserver.emf.common.SingleThreadModelController.handleAction(SingleThreadModelController.java:89) ~[classes/:?]
	at org.eclipse.emfcloud.modelserver.emf.common.SingleThreadModelController.handleNextAction(SingleThreadModelController.java:83) ~[classes/:?]
	at org.eclipse.emfcloud.modelserver.emf.common.SingleThreadModelController.runThread(SingleThreadModelController.java:69) ~[classes/:?]
	... 1 more
2022-04-05 11:33:03,400341100 [JettyServerThreadPool-28] INFO  ProviderDefaults - GET /api/v1/save?modeluri=SuperBrewer3000.coffee -> Status: 200 (took 120.6283 ms)
2022-04-05 11:33:03,402028200 [Thread-17] INFO  AlwaysReload - Model resource 'file:/c:/Users/user/Clients/OpenSource/emfcloud/emfcloud-modelserver-theia/examples/workspace/SuperBrewer3000.coffee' no longer exists.

DiagnosticManager does not populate the problems view

When trying to set the diagnostics to the problems view via the DiagnosticManager the problems view is never actually populated.
After debugging i found out, that this line always results in false:

This prevents the diagnostics to be put into the problems view.

Is there any reason, why a simple undefined check is not enough? The converted object should already be LangServerDiagnostic | undefined.

I tested it and just using if(converted) works.

ModelServerCompoundCommand is missing its CommandKind in field type

During #28 came up, that the ModelServerCompoundCommand provides a type, which equals CommandKind.COMPOUND (= 'compound'). This field is not set, when receiving updates form the ModelServer.
Please evaluate, if we need to customize the default Json ObjectMapper that the command type is properly set or we have to initialize this field on the client.

  • Anyways, the interfaces ModelServerCommand and ModelServerCompoundCommand should be implemented as classes to be able to initialize fields (e.g. the type of the ModelServerCompoundCommand).
  • Please also consider moving the helper methods of ModelServerCommandUtil to the dedicated class implementations.

Subscription does not work using rpc calls

If you want to subscribe to changes from a modelserverclient which is exposed to the frontend using theias proxy, the subscriptions do not work.
The reason is probably that the registered callback is lost and must be offered differently.

Model URIs returned by ModelServer are inconsistent between "/api/v1/models" and "/api/v1/modeluris".

Assume the workspace is in "/home/workspace" and there is a model file "emfmodel.xyz", then calling model server's
"api/v1/models" and "api/v1/modeluris" query result in inconsistent answer. The former returns "file:/home/workspace/emfmodel.xyz", while the latter returns only "emfmodel.xyz".

My use-case is to use the latter query to efficiently get all models on the server and then selectively query the model
server for the details of each of those models.
This is currently not possible, since the "/home/workspace" part cannot be deduced in any way.

This issue is a follow-up on #19.

Introduce FileWatcher concept to notify the Model Server about file changes

At the moment, if resources are manipulated via Theia's default editors (without sending any commands), the Model Server is not notified about file changes.
We should introduce a FileWatcher concept (e.g. listening to file changes and Theia's FileOperations { CREATE, DELETE, MOVE, COPY }) to notify the Model Server. Some default requests are already available in in the model-server-api.ts, and it should be extended by the remaining requests (e.g. addResource, renameResource and so on).

As a first step, we customized the Theia WorkspaceDeleteHandler in the ecore-glsp editor to be able to properly remove resources from the Model Server (see also eclipse-emfcloud/ecore-glsp#96).

Update Readmes

With #65 some parts of the ModelServerClient API have changed.
We should update the readme of the modelserver-theia package accordingly.
Also the new modelserver client package currently has an empty readme which should be completed.

Fix script for downloading model server snapshot

The examples/coffee-theia/scripts/download-server.sh downloads an outdated version of the model server JAR.
In my case, I echoed the the resolved version that is downloaded, which is a snapshot from June 2021.

# Download and copy latest snapshot version org.eclipse.emfcloud.modelserver.example 
org.eclipse.emfcloud.modelserver.example-0.7.0-20210615.062024-55-standalone.jar

Execute integration tests in Jenkins build

We should ensure that the integration tests are executed at least on a regular basis to be aware of possible API breakages.
For the integration tests a running model server instance is needed, which might be a problem to run on the Jenkins instance, but it would be great to include them in the build to avoid issues like eclipse-emfcloud/emfcloud-modelserver#214 for example.

Model Server API v2 in Theia services

Currently, the ModelServerSubscriptionService and ModelServerSubscriptionClient APIs provide support for the Model Server API v2, in the former case via a second interface for the V2 variant of one particular client call-back.

There are two other components in this project that also need updates to support the v2 API:

  • the TheiaModelServerClient interface and its backend RPC implementation that is injected into Theia frontend applications to provide Model Server access. Most likely this would follow the core API interfaces from the @theia/modelserver-client package in providing a second interface for the v2 API. Both would be injected in the container for applications to choose which to pick up. This will allow components such as the model-server-aware variant of the Theia-integrated JSONForms Property View to adopt the v2 API
  • as the primary motivation of the v2 API is the implementation of a Node.js façade for the Model Server, the ModelServerLauncher and its LaunchOptions should be updated to enable optional configuration and launching of that server in addition to the core Java server. This would then allow v2 clients (per the previous item) to connect to the node server's TCP port and, of course, to base request URIs on the api/v2 path instead of api/v1.

Model Server Launcher uses wrong Port Number

The DefaultModelServerNodeLauncher class tells the Java server the wrong port to listen to.

The superclass DefaultModelServerLauncher class launches the Java server with the --port command-line argument set to launchOptions.serverPort. This is correct for the superclass that is used when only the Java server is launched.

But when both the Java server and the Node server are launched, the Java server has to listen on the port that is configured as the Node server's upstream port, because the Java server is upstream of the Node server and the LaunchOptions configuration of the serverPort is the port on which the Node server listens (and to which clients connect).

The DefaultModelServerNodeLauncher class does not modify the Java server launching behaviour of its parent class, so both servers will attempt to listen on the same port and the configuration will not work.

Return to ModelServerSubscriptionService concept

In a previous commit (i.e. 55337ad) we changed the subscription mechanism from ModelServerSubscriptionService to a new interface ModelServerSubscriptionListener.
This turned out to cause problems, as dependency issues occur if a client implements the ModelServerSubscriptionListener interface and uses the ModelServerClient at the same time.
Besides that, the interface didn't come out as handy to implement as expected and on returning to the ModelServerSubscriptionService the clients can consume only those updates they are interested in.

Provide standalone modelserver-client

Currently the model-server client API is nested into the modelserver-theia package and cannot be used in a context without Theia.
AFAIK the model-server client doesn't have any direct Theia dependencies and could be provided in a separate package which facilitates reusing it in a non-Theia application e.g. a plain node back-end.

This is also a good opportunity to discuss the overall architecture of the model-server client.
Currently a simple, custom rest client is used under the hood. While this client suffices to cover the basic usecases it has a couple of downsides:

  • The simple rest client is only working In a node context which limits the reuseability of the model server client as a whole. From a technical point of view there is no real reason for this limitation. Both REST & Websocket work perfectly fine in the browser.
  • The simple rest client as no exception handling concept e.g. throwing an error if a response with status code >200 is received. This forces us to expose low-level response objects via the ModelServer Client API & delegates the exception handling to API uses. With a sophisticated exception handling concept the ModelServer API could directly return the concrete data objects instead of the low level response.
  • There is no way to unit test the ModelServer Client API because a mocking framework for the simple rest client would be required.

I think most of these issues could be resolved by switching to a well-established rest client library like axios. There are also mocking frameworks available for axios which means unit tests could be implemented relativity easy.

We need to be careful with the handling of websockets be able to use the model serve client in both node & browser context. An isomorphic implementation that works in both contexts should be used.

We (EclipseSource) intend to contribute this on behalf of ST Microelectronics.

API v2: Exception on JSON containing null

JSON documents can include null values for properties. And unlike undefined, null is an object type in Javascript but it does not have properties, so the type-util.ts function traverse(...) bombs when trying to copy a null value in transforming JSON between V1 and V2 formats.


type-util.ts:290 Uncaught (in promise) TypeError: Cannot convert undefined or null to object
    at Function.getOwnPropertyNames (<anonymous>)
    at traverse (type-util.ts:290:29)
    at traverse (type-util.ts:306:42)
    at type-util.ts:302:67
    at Array.some (<anonymous>)
    at traverse (type-util.ts:302:51)
    at findProperty (type-util.ts:227:12)
    at isJsonV2 (type-util.ts:223:12)
    at asJsonV2 (type-util.ts:215:12)
    at type-util.ts:199:16

Create generic CustomCommandUtil

The functionality to use custom commands was added as an example in #35 .
It would be great to add a generic CustomCommandUtil or a CustomCommand type in model-server-api.ts.

AddCommand created with constructor can be used only as root

  1. Create an AddCommand with one of the constructors of class
    export class AddCommand extends ModelServerCommand {
  2. Then, try and insert it in a CompoundCommand with constructor of
    export class CompoundCommand extends ModelServerCommand {
  3. When the command is sent to the model server, the model server will try and fail at resolving the references for #objectValues in method org.eclipse.emfcloud.jackson.databind.deser.ReferenceEntry.Base.resolve(DatabindContext, URIHandler).

The cause is that the following line :

(o, i) => new ModelServerReferenceDescription(o.eClass, `//@objectsToAdd.${i}`)

assigns the #objectValues, assuming that the command is the resource's root, with an absolute URI.

In my particular use case, where command was at index 1 (2nd), post-treating the references like this did the trick :

addCommand.objectValues?.forEach(v => {
     v.$ref = v.$ref.replace('//@objectsToAdd.', '//@commands.1/@objectsToAdd.');
});

but this fix is too specific to my use case.

In the general case, the AddCommand constructor can't possibly know where the command will be located in the resource. So I'm not sure what the best fix would be.
Possibilities I can think of :

  • Force the user to indicate where the command will be located, so that we directly insert the correct model reference.
  • Patching references automatically :
    1. leave the constructor as is, with a big shouting warning that the reference may be incorrect
    2. when constructing the CompoundCommand, patching all the model references in contained commands to prepend with the command uri (and also a big shouting warning)
  • A kind of mix, with the possibility to use relative uri fragments or placeholders, which will be patched later...
    Not sure which approach is the best.

[Discussion]Utility method to create json diff commands

In my application, I ended up with some code quite similar to
https://github.com/eclipse-emfcloud/coffee-editor/blob/573830104d9ad541568e6b46f8b3359e8dd0948d/web/coffee-editor-extension/src/browser/coffee-tree/coffee-tree-editor-widget.tsx#L232
(except I use the newer command API, have more comments and minor differences)

I guess any implementation using json forms will have to, at some point, implement such a method to align the modified json with the original by building and executing commands.
Which makes me wonder : shouldn't we provide a utility method wich builds on its own all the commands, rather than letting each user re-implement this ?

I'm not 100% sure all the possible cases are correctly handled here... so maybe there is extra work to perform to make such a utility method. Also, it would probably nice to have an extra configuration attribute to either build the commands for modifications directly on the concerned element or to deep-check for differences in element's children.

Does anyone have extra considerations to bring on this matter ?

Model Server Launcher extensibility

There are some limitations in the extensibility of the Model Server backend process launcher. In my application, I need to add JVM options to configure the JVM for special requirements. These cannot be added to the LaunchOptions::additionalArguments property because those options are sent to the application's main method. JVM options should be specified before the -jar whatever.jar argument on the command-line.

So, in my application I need to rewrite the doStartServer() method to customize the java spawn call. But in doing so, then I lose also the inherited behaviour that launches the Node server, so in my application's custom launcher I have to repeat that also.

It would be nice to improve the extensibility of the launcher service by:

  • adding a jvmArgs property to the LaunchOptions class so that applications can set JVM arguments in addition to application arguments, which would still be in the additionalArgs property
  • factoring out the spawning of the Java server from the DefaultModelServerLauncher::doStartServer() method into a new startJavaServer() method to which the former delegates
  • factoring out the spawning of the Node server from the DefaultModelServerNodeLauncher::doStartServer() method override into a new startNodeServer() method to which the former delegates

The latter two items would ensure that, for applications that still have the (admittedly rare) need to take deeper control of the process spawning, they can do so for either the Java server or the Node server without losing the inherited implementation of the other server.

Keep URI (urijs) usage to a minimum for Theia related packages

Update existing API for Theia-related packages to use Theia's URI type

  • package modelserver-theia
    • update TheiaBackendModelServerClientV2 to use Theia's URI in API and convert internally to URI (urijs)
    • update ModelServerSubscriptionClient to use Theia's URI in API and convert internally to URI (urijs)
    • Edit: Cannot be split efficiently in two parts, will be done with #130
  • package modelserver-markers-theia
    • update DiagnosticManager to use TheiaUri in API and convert internally to URI(urijs)

Support Theia Community Release 1.29.x

Provide Theia URI compatible ModelServerClient

For Theia related components (e.g. command handlers, diagnostic manager) it would be benficial to be able to inject a TheiaModelServerClient that accepts Theia URIs, which are then internally converted to the URI type of the base ModelServerClient

  • package modelserver-theia
    • TheiaModelServerClientApiV2offers the complete API accepting Theia's URI type. Internally converts URI (urijs) and passes on to the ModelServerClientApiV2
  • update tests

[Discussion] Consider typed ModelServerClient interface

I want to open the discussion whether we believe that the ModelServerClient API should be typed.

In general, the model server API is generic (mostly String values) and may support different formats (XMI, JSON, etc.). Therefore it is the responsibility of the provider to actually interpret the string that is returned from the server. The DefaultModelServerClient does not interpret any data and simply returns the String values.

However, as was raised in #20, we may want to provide an interpretation as JSON objects if the format is JSOn. This could be done through an additional implementation of the ModelServerClient interface but would require a generic parameter in that interface, similar to what is provided on the Java side, see [1] and its implementation in [2].

Any thoughts?

[1] https://github.com/eclipse-emfcloud/emfcloud-modelserver/blob/master/bundles/org.eclipse.emfcloud.modelserver.client/src/org/eclipse/emfcloud/modelserver/client/ModelServerClientApiV1.java
[2] https://github.com/eclipse-emfcloud/emfcloud-modelserver/blob/master/bundles/org.eclipse.emfcloud.modelserver.client/src/org/eclipse/emfcloud/modelserver/client/ModelServerClient.java

Optimize Theia test application to show all features of V2

  • Align listener usage to proper v2 usage. In api-test-menu we currently use the ModelServerSubscriptionClient which makes the actual subscription calls confusing, as we pass an undefined listener, but also subscription options (see also #121 (comment)_).
  • We should show the request posted by the menu entry (e.g. data like the request url and its request body - command or patch)
  • Doublcheck if all relevant v2 use cases are covered
  • Doublecheck if we can overall optimize the application for a better overview

Originally posted by @ndoschek in #121 (comment)

[Discussion] Should Diagnostic#collectLeaves merge some parent diagnostics with children ?

Hello folks,

I am encountering a use case where Diagnostic json objects returned by Diagnostic#collectLeaves method have a "-1" uri fragment.

This is due to this validation method :
org.eclipse.emf.ecore.util.EObjectValidator.validate_DataValueConforms(EObject, EAttribute, DiagnosticChain, Map<Object, Object>)
which creates a Diagnostic hierarchy like :

  1. root Diagnostic
  2. child Diagnostic on EObject : "The feature '...' of '...' contains a bad value"
  3. grand-child Diagnostic on the value (without model element, but with an EDataType instead) : "The value '...' must be one of {'...'}"

The #collectLeaves method, as currently implemented, only returns the grand-child Diagnostic, without the associated model EObject.
Nevertheless the relevant information is actually not the grand-child Diagnostic, but rather the concatenation of child Diagnostic and grand-child Diagnostic.
In Theia, since the Problems view can not display an arborescence of Diagnostics like in RCP, I was wondering which was the best course of action for this issue.

Should we :

  • A. Modify the Diagnostics hierarchy directly in the model server to merge such diagnostics and having only relevant leave Diagnostics ? (in org.eclipse.emfcloud.modelserver.emf.common.DefaultModelValidator.validate(String))
  • B. Leave the Diagnostics hierarchy as is and modify the Diagnostic#collectLeaves method to merge leave Diangostics information with the information from their relevant parent Diagnostic ?
  • C. Seek for another way to display Diagnostics, without the Problems view, or with heavy modifications to the Problems view ?

For the moment, I'll patch my application with the A approach, as it is the more easily overrideable one. But I think the B approach would probably be the one making more sense in a general context...

[Edit : the grand-child Diagnostic actually has an EObject, which is not a model element but the EDatatype which makes things worse]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.