eclipse-emfcloud / emfcloud-modelserver-theia Goto Github PK
View Code? Open in Web Editor NEWModelserver Theia integration
License: Other
Modelserver Theia integration
License: Other
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.
We should use "Eclipse emf.cloud Project" as the generic stand-in for all committers and contributors in all poms and package.jsons to avoid having to manually maintain it.
E-mail address: https://accounts.eclipse.org/mailing-list/emfcloud-dev
Web-site the project page: https://projects.eclipse.org/projects/ecd.emfcloud
For details see the discussion in eclipse-glsp/glsp#246
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.
The auto-generated README file is outdated and needs to be updated to reflect the actual installation and startup process.
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 )
As mentioned on Spectrum [1] the getAll
of the client has an incorrect return type and should return a map-like structure that maps from file URI to object.
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.
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.
All example packages may be moved to a dedicated coffee model example repository.
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...
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.
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 ?
Moved here from emfcloud-modelserver/issues/173
With current master and the latest Model Server version, the following workflow does not work under Windows:
edit
request for Coffee.ecore
to set ControlUnit
name to ControlUnitNew
save
request for Coffee.ecore
Coffee.ecore
persists the changesThe 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
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.
The edit
function handles objects of type Operation
or Operation[]
as a second parameter, but this is not reflected in the method signature.
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.
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.
ModelServerCommand
and ModelServerCompoundCommand
should be implemented as classes to be able to initialize fields (e.g. the type of the ModelServerCompoundCommand
).ModelServerCommandUtil
to the dedicated class implementations.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.
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.
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).
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.
Provide some example code in the README file to show how the JavaScript or TypeScript API can be used.
In the Change Model, ChangeDescription#objectsChanges should be objectChanges.
The HTTP endpoints defined in specify the behavior to get all available model URIs in the workspace using GET [...]/modeluris
. This method is missing from the Modelserver API in Theia, cf. modelserver-api.ts
even though it is specified in model-server-paths.ts
.
package.json files have "license": "(EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0)"
whereas I see everywhere else the EPL-2.0 OR MIT.
Given the modifications I've seen, I guess GPL-2.0 is just a remnant which should be replaced with MIT (more permissive).
This also reflects on https://www.npmjs.com/package/@eclipse-emfcloud/modelserver-theia
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
The modelserver-theia packge currently defines a Theia extension but could be migrated to a more general plugin so that it might also be re-used in VS Code.
Add GitHub issue templates to the repository, disable blank issues and add a button that redirects to the emfcloud discussions board for pure questions.
See https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/manually-creating-a-single-issue-template-for-your-repository
If pure ModelServerCommand
used (which applies to using custom commands), ensureCommandPrototype
also has to explicitly the ModelServerCommand
prototype as well, which is currently not the case.
Also enable it for PRs?
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.
We should execute the existing text cases in the CI Jenkins build (preferrably in a separate pipeline step)
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:
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 APIModelServerLauncher
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
.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.
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.
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:
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.
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
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
.
#objectValues
in method org.eclipse.emfcloud.jackson.databind.deser.ReferenceEntry.Base.resolve(DatabindContext, URIHandler)
.The cause is that the following line :
#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 :
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 ?
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:
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
propertyDefaultModelServerLauncher::doStartServer()
method into a new startJavaServer()
method to which the former delegatesDefaultModelServerNodeLauncher::doStartServer()
method override into a new startNodeServer()
method to which the former delegatesThe 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.
Update existing API for Theia-related packages to use Theia's URI type
modelserver-theia
TheiaBackendModelServerClientV2
to use Theia's URI in API and convert internally to URI (urijs)ModelServerSubscriptionClient
to use Theia's URI in API and convert internally to URI (urijs)modelserver-markers-theia
1.29.x
(see https://theia-ide.org/releases/)Compatible Technologies
section on Theia website
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
modelserver-theia
TheiaModelServerClientApiV2
offers the complete API accepting Theia's URI type. Internally converts URI (urijs) and passes on to the ModelServerClientApiV2Currently, the example application only operates with v1
requests.
To simplify future testing, we should add v2
example requests to the api-test-menu
as well.
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
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)_).v2
use cases are coveredOriginally posted by @ndoschek in #121 (comment)
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 :
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 :
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]
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.