Error: UrlError { Unknown URL parameter `ssl-mode' } Rust MySQL - mysql

I am trying to use SSL in my MySQL Connection String but it is giving me this error
Error: UrlError { Unknown URL parameter 'ssl-mode' }
I have referred to official documents from this link: https://dev.mysql.com/doc/refman/8.0/en/connecting-using-uri-or-key-value-pairs.html.
My connection string looks as follows :
----------------------------------------------------------------------------------------------------------
let connection_string = format!("mysql://{}:{}#{}?ssl-mode=REQUIRED", &user_name, &password, &hostname);
----------------------------------------------------------------------------------------------------------
let connection_url: &str = &connection_string;
let pool = Pool::new(connection_url)?;
let mut connection = pool.get_conn()?;
I am still a rookie in using rust. So please let me know if I am doing something wrong here.
Also if possible please suggest me a better way of approaching.
Thank you !!

In order to encrypt your connection to MySQL with TLS/SSL, you need to create an SslOpts instance and pass that to the OptsBuilder instance via its ssl_opts() method.
Here is an example how to create an SslOpts instance via with_danger_accept_invalid_certs():
let builder = OptsBuilder::new();
let opts = builder
.ip_or_hostname(Some("..."))
.db_name(Some("..."))
.user(Some("..."))
.pass(Some("..."))
.ssl_opts(SslOpts::with_danger_accept_invalid_certs(SslOpts::default(), true));
let db_pool = Pool::new_manual(2, 10, opts);
Using with_danger_accept_invalid_certs() is simple, although, as the name suggests, it might not be the most secure option. It should be much more secure than no encryption at all. Depending on your needs, you might want to take a look at the other options provided by the crate.

Related

How to Connect to MySQL database using Swift-Nio

I used node js to connect mysql server and it is working good. I used the API developed in node js and used in the local macOS app. The problem is querying the data from mysql database on workbench is fast but in node js API it is very delay. So, I've to connect mysql db directly from my macOS app.
I installed mysql from here: https://www.mysql.com/downloads/
Also I am using mysql work bench to test the connection and It is connecting without any problem. So, In system preference I've an mysql extensions to start and stop mysql server. In the extension I can see the root folder locate in /usr/local/mysql
I created new project and added swift package of mysql-nio from here
In that repository their API document link is broken https://api.vapor.codes/mysql-nio/master/MySQLNIO/ But I found the correct link https://api.vapor.codes/mysql-nio/main/MySQLNIO/MySQLConnection/
By using that link, I tried to connect with below code,
//https://github.com/vapor/mysql-nio
import Cocoa
import MySQLNIO
class ViewController: NSViewController {
private var group: EventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 4)
private var eventLoop: EventLoop {
return self.group.next()
}
override func viewDidLoad() {
super.viewDidLoad()
do{
let socketAddress = try SocketAddress(ipAddress: "127.0.0.1", port: 3306)
let logger = Logger(label: "MyLogger")
let connection = MySQLConnection.connect(to: socketAddress, username: "root", database: "MyDB", password: "3$#sdRt34#sdf$dja2", tlsConfiguration: nil, serverHostname: nil, logger: logger, on: eventLoop)
connection.whenComplete { result in
switch result{
case .success(let connection):
print("Success! Status closed: \(connection.isClosed)")
case .failure(let error):
DispatchQueue.main.async {
NSApp.presentError(error)
}
}
}
}catch{
NSApp.presentError(error)
}
}
}
Error:
The operation couldn’t be completed. (NIOCore.IOError error 1.)
I added App Transport Security Settings -> Allow Arbitrary Loads to YES in the xcode project info
I don't know How to resolve this issue. Can you please help me to resolve this issue? Thank you!
In the app sandbox, you'll need to enable "Outgoing connections (client)" and then it should work.
Unfortunately, because of a Swift bug the error printout of Swift errors isn't actually useful if you do localizedDescription. To see the actual error, you'd need to put something like a print(error) in your error handler.
See how in the screenshot below, the print(error) prints actually useful text like connect(descriptor:addr:size:): Operation not permitted (errno: 1) if I don't check the "Outgoing connections (client)"?

How to convert Pulumi Output<t> to string?

I am dealing with creating AWS API Gateway. I am trying to create CloudWatch Log group and name it API-Gateway-Execution-Logs_${restApiId}/${stageName}. I have no problem in Rest API creation.
My issue is in converting restApi.id which is of type pulumi.Outout to string.
I have tried these 2 versions which are proposed in their PR#2496
const restApiId = apiGatewayToSqsQueueRestApi.id.apply((v) => `${v}`);
const restApiId = pulumi.interpolate `${apiGatewayToSqsQueueRestApi.id}`
here is the code where it is used
const cloudWatchLogGroup = new aws.cloudwatch.LogGroup(
`API-Gateway-Execution-Logs_${restApiId}/${stageName}`,
{},
);
stageName is just a string.
I have also tried to apply again like
const restApiIdStrign = restApiId.apply((v) => v);
I always got this error from pulumi up
aws:cloudwatch:LogGroup API-Gateway-Execution-Logs_Calling [toString] on an [Output<T>] is not supported.
Please help me convert Output to string
#Cameron answered the naming question, I want to answer your question in the title.
It's not possible to convert an Output<string> to string, or any Output<T> to T.
Output<T> is a container for a future value T which may not be resolved even after the program execution is over. Maybe, your restApiId is generated by AWS at deployment time, so if you run your program in preview, there's no value for restApiId.
Output<T> is like a Promise<T> which will be eventually resolved, potentially after some resources are created in the cloud.
Therefore, the only operations with Output<T> are:
Convert it to another Output<U> with apply(f), where f: T -> U
Assign it to an Input<T> to pass it to another resource constructor
Export it from the stack
Any value manipulation has to happen within an apply call.
So long as the Output is resolvable while the Pulumi script is still running, you can use an approach like the below:
import {Output} from "#pulumi/pulumi";
import * as fs from "fs";
// create a GCP registry
const registry = new gcp.container.Registry("my-registry");
const registryUrl = registry.id.apply(_=>gcp.container.getRegistryRepository().then(reg=>reg.repositoryUrl));
// create a GCP storage bucket
const bucket = new gcp.storage.Bucket("my-bucket");
const bucketURL = bucket.url;
function GetValue<T>(output: Output<T>) {
return new Promise<T>((resolve, reject)=>{
output.apply(value=>{
resolve(value);
});
});
}
(async()=>{
fs.writeFileSync("./PulumiOutput_Public.json", JSON.stringify({
registryURL: await GetValue(registryUrl),
bucketURL: await GetValue(bucketURL),
}, null, "\t"));
})();
To clarify, this approach only works when you're doing an actual deployment (ie. pulumi up), not merely a preview. (as explained here)
That's good enough for my use-case though, as I just want a way to store the registry-url and such after each deployment, for other scripts in my project to know where to find the latest version.
Short Answer
You can specify the physical name of your LogGroup by specifying the name input and you can construct this from the API Gateway id output using pulumi.interpolate. You must use a static string as the first argument to your resource. I would recommend using the same name you're providing to your API Gateway resource as the name for your Log Group. Here's an example:
const apiGatewayToSqsQueueRestApi = new aws.apigateway.RestApi("API-Gateway-Execution");
const cloudWatchLogGroup = new aws.cloudwatch.LogGroup(
"API-Gateway-Execution", // this is the logical name and must be a static string
{
name: pulumi.interpolate`API-Gateway-Execution-Logs_${apiGatewayToSqsQueueRestApi.id}/${stageName}` // this the physical name and can be constructed from other resource outputs
},
);
Longer Answer
The first argument to every resource type in Pulumi is the logical name and is used for Pulumi to track the resource internally from one deployment to the next. By default, Pulumi auto-names the physical resources from this logical name. You can override this behavior by specifying your own physical name, typically via a name input to the resource. More information on resource names and auto-naming is here.
The specific issue here is that logical names cannot be constructed from other resource outputs. They must be static strings. Resource inputs (such as name) can be constructed from other resource outputs.
Encountered a similar issue recently. Adding this for anyone that comes looking.
For pulumi python, some policies requires the input to be stringified json. Say you're writing an sqs queue and a dlq for it, you may initially write something like this:
import pulumi_aws
dlq = aws.sqs.Queue()
queue = pulumi_aws.sqs.Queue(
redrive_policy=json.dumps({
"deadLetterTargetArn": dlq.arn,
"maxReceiveCount": "3"
})
)
The issue we see here is that the json lib errors out stating type Output cannot be parsed. When you print() dlq.arn, you'd see a memory address for it like <pulumi.output.Output object at 0x10e074b80>
In order to work around this, we have to leverage the Outputs lib and write a callback function
import pulumi_aws
def render_redrive_policy(arn):
return json.dumps({
"deadLetterTargetArn": arn,
"maxReceiveCount": "3"
})
dlq = pulumi_aws.sqs.Queue()
queue = pulumi_aws.sqs.Queue(
redrive_policy=Output.all(arn=dlq.arn).apply(
lambda args: render_redrive_policy(args["arn"])
)
)

Swift Vapor3 Raw SQL query with new connection

I'm attempting to use Vapor3 to perform raw SQL queries. The supplied documentation for this kind of thing is pretty vague on the website unfortunately.
Essentially I want to do something like:
router.get("example") { req -> Future<View> in
let leaf = try request.make(LeafRenderer.self)
// I can't get this next bit to work. Does anyone have any ideas how to do this? I seem to get all sorts of Xcode errors with .mysql, closures etc.
let users = try request.withNewConnection(to: .mysql) { connection -> EventLoopFuture<[User]>
return try connection.raw("select * from users").all(decoding: User.self)
}
var context = [String: String]()
context["user"] = users
return leaf.render("example", context)
}
Any help on want I'm doing wrong here would be greatly appreciated.
Thanks in advance,
Matt
You code was failing because you aren't implementing the closure properly. Your route returns in the let users... closure so the second return is never reached.
This works:
router.get("example")
{
insecure.get("example") {
request -> Future<View> in
return request.withNewConnection(to: .mysql) {
connection in
return connection.raw("select * from User").all(decoding: User.self).flatMap(to:View.self) {
users in
return try request.make(LeafRenderer.self).render("example",["users":users])
}
}
}
}
The changes are:
There's no need to define leaf until you need it.
The definition of users is now inside the closure.

SOLRJ - index info how to query for it

I found out that when we enter admin page of my SOLR server there is such a request:
http://localhost:8983/solr/documents/admin/luke?wt=json&show=index&numTerms=0
This request is getting some basic informations about index such as last modified etc. I want to create query using SOLRJ but I can't. My code is very simple:
SolrClient server = new HttpSolrClient("http://localhost:8983/solr/documents/admin");
SolrQuery solrQuery = new SolrQuery("luke?wt=json&show=index&numTerms=0");
QueryResponse response = null;
SolrParams solrParams = solrQuery;
response = server.query(solrParams);
logger.error("PING: " + response.getElapsedTime());
for(SolrDocument doc: response.getResults())
{
for(String key: doc.keySet())
{
logger.error("KEY: "+key+" VAL: "+doc.get(key));
}
}
logger.error("TEST after");
I got error Problem accessing /solr/docs/admin/select wich isn't something strange. Should I use simple GET and parse JSON or there is some other way to use SOLRJ for this one ?
I guess the correct url for accessing the solr end point should be:
SolrClient server = new HttpSolrClient("http://localhost:8983/solr/documents");
Assuming the core name for your solr setup is documents.
The default handler is /select handler.

Examining the Windows Store apps AppxManifest at Runtime

I try to load the AppxManifest at Runtime to read out the Version of the app. I fond this article:
http://tonychampion.net/blog/index.php/2013/01/examining-the-windows-store-apps-appxmanifest-at-runtime/#comments
I tried the line from the post:
var doc = XDocument.Load("AppxManifest.xml", LoadOptions.None);
But this will throw me the following exception:
{System.Xml.XmlException: An internal error has occurred.
at System.Xml.XmlXapResolver.GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn)
at System.Xml.XmlTextReaderImpl.FinishInitUriString()
at System.Xml.XmlTextReaderImpl..ctor(String uriStr, XmlReaderSettings settings, XmlParserContext context, XmlResolver uriResolver)
at System.Xml.XmlReaderSettings.CreateReader(String inputUri, XmlParserContext inputContext)
at System.Xml.XmlReader.Create(String inputUri, XmlReaderSettings settings, XmlParserContext inputContext)
at System.Xml.Linq.XDocument.Load(String uri, LoadOptions options)
at MyMedi.Src.Utilities.GetVersion()
at MyMedi.WindowsPhone.Test.Src.UtilitiesTest.Utilities_GetVersionTest()}
Can anyone tell me what I'm doing wrong?
Thanks
NPadrutt
I'm not sure why you'd want to, but you could try loading the document with the ms-appx:// uri schema in the file reference.
There's a much easier way to achieve your goal, though.
Package package = Package.Current;
PackageId packageId = package.Id;
PackageVersion version = packageId.Version;
var versionString = string.Format(
CultureInfo.InvariantCulture,
"{0}.{1}.{2}.{3}",
version.Major,
version.Minor,
version.Build,
version.Revision);