Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bugfix][Server] Add WMS SLD parameter support #7859

Merged
merged 4 commits into from
Sep 29, 2018

Conversation

rldhont
Copy link
Contributor

@rldhont rldhont commented Sep 11, 2018

Description

Fixed #19795 QGIS Server 3 / WMS: the SLD parameter support has been removed https://issues.qgis.org/issues/19795

To reactivate SLD parameter support, we add a new conversion capability in server parameter toUrl. And the capabilty to load the content associted to an URL.

Then if the SLD parameter is defined, the content is loaded and the SLD_BODY is set.

Checklist

  • Commit messages are descriptive and explain the rationale for changes
  • Commits which fix bugs include fixes #11111 in the commit message next to the description
  • I have read the QGIS Coding Standards and this PR complies with them
  • This PR passes all existing unit tests (test results will be reported by travis-ci after opening this PR)
  • New unit tests have been added for core changes
  • I have run the scripts/prepare-commit.sh script before each commit

@rldhont rldhont added Requires Tests! Waiting on the submitter to add unit tests before eligible for merging Bugfix labels Sep 11, 2018
@rldhont rldhont added this to the 3.4 milestone Sep 11, 2018
@pblottiere
Copy link
Member

Hi @rldhont,

There's currently a unit test for the SLD parameter (test_wms_getmap_sld) and the rendered image seems OK. How is it possible?

Moreover, I saw you added a SLD_BODY parameter. Can you give an example of a request for my education please?

Thanks :).

@rldhont
Copy link
Contributor Author

rldhont commented Sep 11, 2018

Hi @pblottiere,

SLD_BODY is for the XML url encoded, and SLD is for an URL. The tests has to be updated to use SLD_BODY param and not SLD

@pblottiere
Copy link
Member

SLD_BODY is for the XML url encoded, and SLD is for an URL. The tests has to be updated to use SLD_BODY param and not SLD

Thanks for the explanation 👍

@rldhont
Copy link
Contributor Author

rldhont commented Sep 11, 2018

@pblottiere it's green!

@@ -200,6 +205,107 @@ QgsRectangle QgsServerParameterDefinition::toRectangle( bool &ok ) const
return extent;
}

QByteArray QgsServerParameterDefinition::loadUrl( bool &ok ) const
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @nyalldawson,

I'm not very familiar with the QgsNetworkAccessManager class. Can you take a look on this method in particular to give me your opinion please?

Thanks :)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar with the design of server, but calling QCoreApplication::processEvents on the main thread is dangerous in app. I don't think that's an issue here as my understanding is that server does everything on the main thread?

There is a class QgsNetworkContentFetcher which handles the redirections etc for you, so it would be good to see that used to avoid duplicated code handling this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't use QgsNetworkContentFetcher because I can't use connect because QgsServerParameterDefinition does not derived QObject.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nyall is right, it would avoid a lot of duplicated code.

Why is it not possible to just use QgsNetworkContentFetcher in the same way as QgsLayoutItemHtml (for example in the fetchHtml method)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has explain, QgsServerParameterDefinition is not derived from QObject so it's not possible to use connect in this context. So I can't do like QgsLayoutItemHtml

connect( mFetcher, &QgsNetworkContentFetcher::finished, &loop, [&loaded, &loop ] { loaded = true; loop.quit(); } );

If you have an idea, how I can use QgsNetworkContentFetcher I'm interested.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't you call QObject:: connect?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @nyalldawson it's done.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pblottiere done ;-)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, it's much better this way. Thanks @rldhont :)

QByteArray ba = mWmsParameters[ QgsWmsParameter::SLD ].loadUrl();
if ( !ba.isEmpty() )
{
const QString sldBody = QString::fromStdString( ba.toStdString() );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rldhont Do you think that the string conversion could be hidden in the loadUrl() method?

@@ -364,7 +381,7 @@ namespace QgsWms
* Returns SLD if defined or an empty string.
* \returns sld
*/
QString sld() const;
QString sldBody() const;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you update the documentation accordingly?

@pblottiere
Copy link
Member

Hi @rldhont,

Apart from some minor comments, I just would like an opinion on the use of QgsNetworkAccessManager because I never used it myself (especially on the while loops).

Otherwise, the code looks good!

Thanks :)

@rldhont
Copy link
Contributor Author

rldhont commented Sep 11, 2018

Thanks @pblottiere for the review

@rldhont rldhont changed the title [Bugfix][Server[WIP]] Add WMS SLD parameter support [Bugfix][Server] Add WMS SLD parameter support Sep 12, 2018
@rldhont
Copy link
Contributor Author

rldhont commented Sep 12, 2018

@pblottiere done


// Do the request
QNetworkReply *reply = nullptr;
// The following code blocks until the file is downloaded...
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there some kind of timeout mechanism in this case (to avoid an infinite loop)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which duration ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pblottiere I have added a timeout mecahnism.

@rldhont rldhont removed the Requires Tests! Waiting on the submitter to add unit tests before eligible for merging label Sep 13, 2018
@nyalldawson nyalldawson modified the milestones: 3.4, 3.4.0 Sep 14, 2018
@rldhont rldhont force-pushed the fix-server-sld-param-support branch 2 times, most recently from 5e9fed0 to e9d4442 Compare September 16, 2018 17:22
QEventLoop loop;
QObject::connect( &fetcher, &QgsNetworkContentFetcher::finished, &loop, &QEventLoop::quit );

QgsMessageLog::logMessage( QStringLiteral( "Request started [url: %1]" ).arg( url.toString() ) );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tr(...)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wondering what happens here if the connection requires authentication ... unfortunately the current implementation of authmanager cannot automatically inject the authentication configuration based on a domain (and we probably don't want to do that without user confirmation or authentication configuration).

Not a blocker, but something that needs to be considered.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pblottiere which class in the server is provided tr(...) ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

found ad done

if ( !reply )
{
ok = false;
QgsMessageLog::logMessage( QStringLiteral( "Request failed [error: no reply - url: %1]" ).arg( url.toString() ) );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tr(...)

ok = false;
if ( reply->error() != QNetworkReply::NoError )
{
QgsMessageLog::logMessage( QStringLiteral( "Request failed [error: %1 - url: %2]" ).arg( reply->errorString(), reply->url().toString() ) );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tr(...)

QgsMessageLog::logMessage( QStringLiteral( "Request failed [error: %1 - url: %2]" ).arg( reply->errorString(), reply->url().toString() ) );
}
QVariant phrase = reply->attribute( QNetworkRequest::HttpReasonPhraseAttribute );
QgsMessageLog::logMessage( QStringLiteral( "Request error [status: %1 - reason phrase: %2] for %3" ).arg( status.toInt() ).arg( phrase.toString(), reply->url().toString() ) );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tr(...)

if ( reply->error() != QNetworkReply::NoError )
{
ok = false;
QgsMessageLog::logMessage( QStringLiteral( "Request failed [error: %1 - url: %2]" ).arg( reply->errorString(), reply->url().toString() ) );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tr(...)

if ( !ok )
{
const QString msg = QString( "%1 request error for %2" ).arg( name( mName ), url.toString() );
QgsMessageLog::logMessage( msg );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tr(...)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The message is also raised and be displayed in an OGC Exceptions. You wrote in #8006 discussion that messages in OGC Exceptions does not have to be localized.

I can removed the logMessage because QgsServerParameterDefinition already logs messages.
What do you think ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The message is also raised and be displayed in an OGC Exceptions. You wrote in #8006 discussion that messages in OGC Exceptions does not have to be localized.

Indeed.

I can removed the logMessage because QgsServerParameterDefinition already logs messages.
What do you think ?

Indeed :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done @pblottiere thanks!

Fixed qgis#19795 QGIS Server 3 / WMS: the SLD parameter support has been removed

To reactivate SLD parameter support, we add a new conversion capability in server parameter `toUrl`. And the capabilty to load the content associted to an URL.

Then if the SLD parameter is defined, the content is loaded and the SLD_BODY is set.
@rldhont rldhont merged commit ad7d03c into qgis:master Sep 29, 2018
@rldhont rldhont deleted the fix-server-sld-param-support branch February 7, 2019 21:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants