Connect external language server to VSCode extension - visual-studio-code

I want to implement a VSCode extension that uses the Language Server Protocol, but I want the server component to be on an actual server (in the cloud), and not a part of the VSCode extension.
Can I set the client extension to connect to a server via websockets or HTTP?

Multiple ServerOptions are supported when you initialize a LanguageClient according to the signature of ServerOptions.
you can use the StreamInfo if you want to use a real remove server as your language server. Here is a sample code to connect to your server via WebSocket and initialize a LanguageClient.
const connection = connectToServer(hostname, path);
const client = new LanguageClient(
"docfxLanguageServer",
"Docfx Language Server",
() => Promise.resolve<StreamInfo>({
reader: connection,
writer: connection,
}),
{});
private connectToServer(hostname: string, path: string): Duplex {
const ws = new WebSocket(`ws://${hostname}/${path}`);
return WebSocket.createWebSocketStream(ws);
}

I am not sure if you can control the location of the language server, but there is another option. You do not need to implement the Language Server Protocol to, for example, provide parsing help. In that case you can implement your own convenient parsing service API (tailored to the nature of the language you want to support).
Within your extension you subscribe to workspace edit events using workspace.onDidChangeTextDocument
Re-start a 1sec timeout every time the file on-change event is raised
When the timeout expires without any further file modification, gather all relevant files and send them to your parsing server
In your extension, create a DiagnosticCollection using https://code.visualstudio.com/api/references/vscode-api#languages.createDiagnosticCollection and replace populate it with the warnings/errors/hints resulting from the parsing server in the cloud.
Subscribe to other workspace events, e.g. workspace.onDidOpenTextDocument or workspace.onDidCloseTextDocument in order to keep the DiagnosticCollection content relevant

Related

dynamicaly parameterized FeignClients

I need to access different instances of a server sharing the same REST interface.
for one server, or different instances of the same server, I would use Ribbon and a feignClient, but the servers are not interchangeable.
I've got a list of server adresses in my application.yml file, likewise:
servers:
- id: A
url: http://url.a
- id: B
url: http://url.b
I'd like to be able to request a server regarding input parameter, for example:
ClientA -> /rest/api/request/A/get -> http://url.a/get
ClientB -> /rest/api/request/B/get -> http://url.b/get
The middleware is agnostic regarding the clients, but the backend server is bound to the clients.
many clients -> one middleware -> some clients
Who would you achieve that using Feign? is it even possible?
The simplest way is to create two Feign targets using the reusing the interface and builder.
Client clientA = Feign.builder()
.target(Client.class, "https://url.a");
Client clientB = Feign.builder()
.target(Client.class, "https://url.b");
This will create a new Client for each target url, however, by ensuring that the supporting components such as the Encoder, Decoder, Client, and ErrorDecoder are singleton instances and thread-safe, the cost of the client will be minimal.
If you don't want to create multiple clients, the alternative is to include a URI as a method parameter.
#RequestLine("POST /repos/{owner}/{repo}/issues")
void createIssue(URI host, Issue issue, #Param("owner") String owner, #Param("repo") String repo);
The value host in the example above will replace the base uri provided in the builder. The drawback to this approach you will need to modify your interface to add this URI to the appropriate methods and adjust the callers to supply the target.

Using GitHub API from Indy in Delphi

I'm working on a project in Delphi 10.1 Berlin which integrates with GitHub. This project intends to download repositories via ZIP files. However, I'm facing some issues.
Originally, I chose (as always) to use Indy to integrate with the GitHub API. I've always used Indy for all web API consumption. However, I'm not having any success using it with GitHub.
The API requires HTTPS. I have obtained the latest OpenSSL DLLs for use with Indy, and am using the Indy library with Delphi 10.1 Berlin.
I have setup a TIdHTTP component with a TIdSSLIOHandlerSocketOpenSSL attached. I've set that IO Handler to all the Method options available, and not one gives me a valid response. I get one of two different responses...
When using sslvSSLv3, I get: error:14094410:SSL routines: SSL3_READ_BYTES:sslv3 alert handshake failure.
When using sslvTLSv1_2, I get: error:1409442E:SSL routines:SSL_READ_BYTES:tlsv1 alert protocol version
I had to resort to TRESTClient for now just to be able to work with the API. But it doesn't handle binary properly.
The test is as simple as https://api.github.com. I can call that in Chrome and Postman, and get a response. Just not via Indy.
How can I accomplish a connection with GitHub's API via Delphi's Indy library?
This Indy HTTP subclass works with the GitHub API.
type
TIndyHttpTransport = class(TIdCustomHTTP)
public
constructor Create;
end;
implementation
uses
IdSSLOpenSSL;
{ TIndyHttpTransport }
constructor TIndyHttpTransport.Create;
var
SSLIO: TIdSSLIOHandlerSocketOpenSSL;
begin
inherited Create;
HTTPOptions := HTTPOptions + [hoNoProtocolErrorException, hoWantProtocolErrorContent];
SSLIO := TIdSSLIOHandlerSocketOpenSSL.Create(Self);
SSLIO.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
SSLIO.SSLOptions.Mode := sslmClient;
SSLIO.SSLOptions.VerifyMode := [];
SSLIO.SSLOptions.VerifyDepth := 0;
Self.IOHandler := SSLIO;
// Request.UserAgent := 'my useragent string';
end;
Maybe your code also needs to modify the user agent string (because I use this code with different service providers, not only GitHub. Some of them require a modified user agent string instead of the default).
Source: https://github.com/michaelJustin/daraja-framework/blob/master/demo/common/IndyHttpTransport.pas

MQTT connection creation and subscribe

I'm setting up a new mqtt conection in my app but there is a problem when i would like to create the main connection of mqtt.
I'm using mqtt.js.
I've tried all what is done in MQTT documentation but nothing happens..
mqttFunction(){
var mqtt = require('mqtt');
var client = mqtt.connect([{host: 'localhost', port: '1883'},]);
client.subscribe('presence')
client.on('message', function (topic, message) {
console.log(message);
});
}
I expect the output of the mqtt broker to be 'ON' when i asked it to respond.
The error is: ERROR ReferenceError: process is not defined
The documentation you followed is intended for Node.js and various other back-end JavaScript frameworks. Even though it uses NPM, Ionic ultimately produces a front-end framework, and its applications run a bit differently.
For example, Ionic programs may not have a global process variable like Node.js. mqtt.js expects this variable, with code like:
if (commist.parse(process.argv.slice(2)) !== null){...}
You could declare a process object, and get past this particular error. Other obstacles could come up.
var process = {env : {NODE_ENV: 'production'}}
If there are still issues with that, you could try the instructions for browser usage, which point to a specially compiled version, like https://unpkg.com/mqtt#3.0.0/dist/mqtt.min.js. I have had less luck with mqtt.js in the browser, and you may want an alternative like web-mqtt-cient / Paho if more complex connections are involved.

IPython Javascript client API

Does IPython provide a Javascript client API for interfacing to a kernel server?
I had a look at https://ipython.org/ipython-doc/dev/development/messaging.html which explains the wire protocol between a front-end and a kernel.
I would be interested in finding out how the current web client communicates with a kernel and in particular how I could leverage JavaScript in order to programmatically create new notebooks from my own custom web client
Thanks
See https://gist.github.com/disarticulate/d06069ff3e71cf828e5329beab8cb084
There you can see a nice example:
// a very basic output handling
var handle_output = function (data) {console.log(data);}
//callbacks is an object whose so special, it appears to only have been documented in
//the source code, as no only google found me a link.
//callbacks.iopub.output is used to get the data from execute
var callbacks = {
iopub : {
output : handle_output,
}
}
//execute anything you want; if a string value is returned
//you can print it out and pass it to the callbacks
//(or do other things, no idea, it's poorly documented online
//(read the source F12->static/notebook/js/services/kernels/kernel.js)
//kernel.js/Kernel.prototype.execute
var kernel = IPython.notebook.kernel;
kernel.execute("print(json.dumps(python_dict))",callbacks)
You can see the definition going to in /static/services/kernels/kernel.js

How do I set the MSMQ Message Extension Using BizTalk's MSMQ Adapter?

We are using BizTalk Server to send messages via MSMQ. The receiving system requires that each message have the extension property set to a guid (as a byte array). MSDN documents the Extension property of the MSMQMessage here and (in .NET) here.
It is simple to set the extension property in .NET:
const string messageContent = "Message content goes here";
var encodedMessageContent = new UTF8Encoding().GetBytes(messageContent);
// Create the message and set its properties:
var message = new System.Messaging.Message();
message.BodyStream = new System.IO.MemoryStream(encodedMessageContent);
message.Label = "AwesomeMessageLabel";
// Here is the key part:
message.Extension = System.Guid.NewGuid().ToByteArray();
// Bonus! Send the message to the awesome transactional queue:
const string queueUri = #"FormatName:Direct=OS:localhost\Private$\awesomeness";
using (var transaction = new System.Messaging.MessageQueueTransaction())
{
transaction.Begin();
using (var queue = new System.Messaging.MessageQueue(queueUri))
{
queue.Send(message, transaction);
}
transaction.Commit();
}
However, BizTalk's MSMQ adapter does not surface the message extension as something that can be set (refer to the list of adapter properties on MSDN). I also decompiled the Microsoft.BizTalk.Adapter.MSMQ.MsmqAdapter assembly that ships with BizTalk 2013 and can find no reference to the extension property.
How can I set the extension of the MSMQ message sent by BizTalk? I would prefer to not have to create a custom adapter, if possible, as that requires a large amount of overhead and ongoing maintenance.
Did you see this article? http://msdn.microsoft.com/en-us/library/aa560725.aspx
The article shows how to programmatically set an MSMQ receive location; additionally, it exposes access to secondary properties that might be necessary but not shown by the default BizTalk adapter - (e.g. Extension)
.
ManagementClass objReceiveLocationClass =
new ManagementClass(
"root\\MicrosoftBizTalkServer",
"MSBTS_ReceiveLocation",
null);
// Create an instance of the member of the class
ManagementObject objReceiveLocation =
objReceiveLocationClass.CreateInstance();
// Fill in the properties
objReceiveLocation["Name"] = name;
objReceiveLocation["ReceivePortName"] = port;
objReceiveLocation["AdapterName"] = adapterName;
objReceiveLocation["HostName"] = hostName;
objReceiveLocation["PipelineName"] = pipeline;
objReceiveLocation["CustomCfg"] = customCfg;
objReceiveLocation["IsDisabled"] = true;
objReceiveLocation["InBoundTransportURL"] = inboundTransport;
// Put the options -- creates the receive location
objReceiveLocation.Put(options);
EDIT:
After decompiling the BizTalk MSMQ adapter code down to the interface level, I don't see a way of doing this using the default adapter. The adapter can't be extended either as it is sealed.
The only other options I've found are
Create a custom adapter (as you have already listed)
hack 1: Place the data in a property that IS accessible by the MSMQ Adapter (e.g. Label), intercept the message with an external process, transform it there.
hack 2: Use a custom adapter that is already written to call a powershell script and do the necessary transformation/transmission in that script. http://social.technet.microsoft.com/wiki/contents/articles/12824.biztalk-server-list-of-custom-adapters.aspx#BizTalk_PowerShell_Adapter
hack 3: Redefine the requirements. E.g. get the receiver to change the required field from Extension to something that is available (e.g. Label).
hack 4: Attempt to find a way to send the message via the WCF-MSMQ adapter. http://msdn.microsoft.com/en-us/library/system.servicemodel.netmsmqbinding.aspx
EDIT:
(The reason why you SHOULDN'T set the extension property)
The Extension property is used to link large messages together which get fragmented in transport if the total message size is over 4MB. This is done under the covers and if circumvented can cause the corruption of large messages.
To participate in large message exchanges, the message queuing computer must have the Mqrtlarge.dll file installed, and the message queuing application should use the add-on APIs. Otherwise, complete messages will be fragmented.
BizTalk 2004 Large Message Extension Documentation
BizTalk 2010 Large Message Extension Documentation