Skip to main content
Woohoo! Qlik Community has won “Best in Class Community” in the 2024 Khoros Kudos awards!
Announcements
Nov. 20th, Qlik Insider - Lakehouses: Driving the Future of Data & AI - PICK A SESSION
cancel
Showing results for 
Search instead for 
Did you mean: 
Not applicable

EDX Triggers Not Working Since 11 Upgrade

We have recently upgraded our test environment from Qlikiview 10 to Qlikview 11 so as to evaluate the changes and confirm that existing reports and functions still work

As it stands the only functionality that has failed to work in qlikview 11 is the EDX triggers

I have done a significant amount of net research around this area but can find no article that concretely states that EDX trigger that work in QV 10 will not work in QV 11

When we attempt to fire the EDX trigger we get the following error:

17/10/2014 12:06:08-The remote server returned an error: (404) Not Found.

17/10/2014 12:06:08-Runtime exception encountered

Is this due to the existing EDX code no longer working in QV 11?

The EDX trigger we currently have implemented is an exe written in c# and as yet I can find no example of how to re-write an EDX exe in c# (the only example I can fin is for a DLL and this does not appear to translate into an exe)

Here is a code snippet from our existing EDX trigger code:

bool blnStartTask = sqlHelper.execSQL("SELECT * FROM [database].[flagtable] WHERE TRUNC(rptdate) = trunc(sysdate-1)");

                    //bool blnStartTask = sqlHelper.execSQL("SELECT * FROM [database].[flagtable] WHERE TRUNC(rptdate) = trunc(sysdate)");

                    if (blnStartTask == true)

                    {

                        //Indicates that the data migration from gold to goldmine is completed

                        status = true;

                        // Settings

                        string Result = "";

                        string QvsAddress = ConfigurationManager.AppSettings["server"];

                        string TaskName = ConfigurationManager.AppSettings["task"];

                        string EDXPassword = ConfigurationManager.AppSettings["password"];

                      

                        // Create class

                        EDXCall Caller = new EDXCall();

                        // Obtain a EDX key from QVS

                        string EDXKey = Caller.GetEDXKey(QvsAddress);

                        // Call the EDX to execute the task in QVS

                        Result = Caller.LaunchEDX(QvsAddress, EDXKey, EDXPassword, TaskName);

                        //Log the result after executing the task

                        Logger.log(Result);

                        Result = Caller.CheckEDXStatus(QvsAddress, EDXKey, TaskName);

                        Logger.log("EDX Task Completed");

16 Replies
amit_saini
Master III
Master III

Peter_Cammaert
Partner - Champion III
Partner - Champion III

In QV11 the interface for EDX triggers has changed completely. While in QV10 an EDX trigger would launch a direct function call to the QDS service, the whole procedure now passes through the QMS (QlikView Management Service) API, which is a different interface.

You may have to reprogram your EDX setup.

You may be interested in these:

EDX trigger QV10 TO11

Using EDX in QlikView 11

Not applicable
Author

We still have yet to resolve this issue and all suggested solution so far have directed it to documentation we have already seen and does not appear to apply to our specific situation

Can someone provide a specific example that relates to using EDX trigger in qv 11 for an exe that is dependent on a database entry to fire a Qlikview task - i.e. the trigger is there to start the Qlikview task when the data has been completely loaded into the data source table

Not applicable
Author

Hi Thomas,

Can you just upload the EDX C# Code..

Not applicable
Author

I have published the code on the qlik community site

http://community.qlik.com/docs/DOC-7811

agomes1971
Specialist II
Specialist II

Hi,

your code will never run.

it's lacking the service reference...

please rebuild your code

based on this

QlikView Management API - #1 Setting up a Visual Studio project

HTH

André Gomes

agomes1971
Specialist II
Specialist II

Hi,

and more:

The QlikView Management Service API

The QlikView Management Service (QMS) API is exposed as a web service and provides a description of its operations and data objects in WSDL available at http://<server-name>:4799/QMS/Service by default. All communication is using SOAP over HTTP.

To be able to interact with the QMS API web service, a key refered to as the "service key" must be supplied as a header of the HTTP request of each operation call, except for the GetTimeLimitedServiceKey operation which is used to retrieve such a key. This aims to prevent cross-site request forgery (CSRF), see the CSRF article at OWASP.org for more information. The HTTP header containing the service key is called X-Service-Key. For example, the header with a value can look like this:

X-Service-Key: rPnBL6zlbvNr5k2nowI919EJkkOeHsi8

Different security layers controls the access to the different operations. Most operations require membership of a local group named QlikView Management API which aims to control overall API access. Exception to this is the GetTimeLimitedServiceKey operation and EDX related operations. The second layer of security aims to control access at an operation level and involves the local groups QlikView Administrator and QlikView EDX as well as the Document Folder Administrator role. These roles are inclusive, where QlikView Administrator provides the highest access level and QlikView EDX the lowest; e.g. a Document Folder Administrator have access to operations that require QlikView EDX membership, and a QlikView Administrator have access to operations that require Document Folder Administrator membership. Each operation's documentation specifies what exact roles are required to access it.

Using the QlikView Server 11 SDK sample code

The QlikView Server 11 SDK can be installed as a part of the QlikView Server 11 installation and contains a couple of examples on how to use the QMS API. It also contains a code example on how to inject the service key into the HTTP headers of the API web service call. This example is written in C# .NET 3.5 and assumes that the application is using WCF to communicate with the API.

See Also: Samples

Collapse imageNavigating this API reference

The available QMS API operations are listed under the IQMSBackend interface under the QMSBackendInterface namespace. All data objects used by these operations are listed under the three PIX.QMSAPI.DataObjects namespaces. These namespaces are internal QlikView Management Service namespaces and will be used mainly as references in the SOAP XML.

This code sample is written in C# based on .NET Framework 4.0 and WCF. It demonstrates how to inject the service key into the HTTP header of each QMS API web service call.

Certificate: Both the URL for connecting to the API and the content of the app.config file differers slightly if a certificate is used so please read the sample carefully.

Installing the certificate is beyond the scope of this sample.

To build and run this example

Create a new C# Console Application project and name it MyTestApplication

Make sure you have the QlikView Management Service running

Right-click the References node in the Solution Explorer and select Add Service Reference

Enter the QMS API WSDL address http://<server-name>:4799/QMS/Service and click Go

Certificate: If the QlikView Management Service has been configured to use certificate security, you must use https instead, i.e: https://<server-name>:4799/QMS/Service

Enter QMSAPI as name for the service reference namespace

[Optionally] Click on Advanced, select System.Collections.Generic.List for Collection Type and click OK

Click OK to have Visual Studio automatically generate code for communication with the QMS API web service

Right-click the References node in the Solution Explorer and select Add Reference

Under the .NET tab, select System.Configuration and click OK

Replace everything in Program.cs with the following code:

CopyC#

using System;

using System.Collections.Generic;

using System.ServiceModel;

using System.ServiceModel.Channels;

using System.ServiceModel.Configuration;

using System.ServiceModel.Description;

using System.ServiceModel.Dispatcher;

using MyTestApplication.QMSAPI;

namespace MyTestApplication

{

    class ServiceKeyBehaviorExtensionElement : BehaviorExtensionElement

    {

        public override Type BehaviorType

        {

            get { return typeof(ServiceKeyEndpointBehavior); }

        }

        protected override object CreateBehavior()

        {

            return new ServiceKeyEndpointBehavior();

        }

    }

    class ServiceKeyEndpointBehavior : IEndpointBehavior

    {

        public void Validate(ServiceEndpoint endpoint) { }

        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)

        {

            clientRuntime.MessageInspectors.Add(new ServiceKeyClientMessageInspector());

        }

    }

    class ServiceKeyClientMessageInspector : IClientMessageInspector

    {

        private const string SERVICE_KEY_HTTP_HEADER = "X-Service-Key";

        public static string ServiceKey { get; set; }

        public object BeforeSendRequest(ref Message request, IClientChannel channel)

        {

            object httpRequestMessageObject;

            if (request.Properties.TryGetValue(HttpRequestMessageProperty.Name, out httpRequestMessageObject))

            {

                HttpRequestMessageProperty httpRequestMessage = httpRequestMessageObject as HttpRequestMessageProperty;

                if (httpRequestMessage != null)

                {

                    httpRequestMessage.Headers[SERVICE_KEY_HTTP_HEADER] = (ServiceKey ?? string.Empty);

                }

                else

                {

                    httpRequestMessage = new HttpRequestMessageProperty();

                    httpRequestMessage.Headers.Add(SERVICE_KEY_HTTP_HEADER, (ServiceKey ?? string.Empty));

                    request.Properties[HttpRequestMessageProperty.Name] = httpRequestMessage;

                }

            }

            else

            {

                HttpRequestMessageProperty httpRequestMessage = new HttpRequestMessageProperty();

                httpRequestMessage.Headers.Add(SERVICE_KEY_HTTP_HEADER, (ServiceKey ?? string.Empty));

                request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessage);

            }

            return null;

        }

        public void AfterReceiveReply(ref Message reply, object correlationState) { }

    }

    class Program

    {

        static void Main(string[] args)

        {

            try

            {

                // create a QMS API client

                IQMS apiClient = new QMSClient();

                //If you want to connect to a server different from the one used when creating the service reference,

                //do as follows:                              

                //

                //NTLM only (default installation)

                //IQMS apiClient = new QMSClient("BasicHttpBinding_IQMS", "http://remotehost:4799/QMS/Service");

                //

                //Certificate security

                //IQMS apiClient = new QMSClient("WSHttpBinding_IQMS", "https://remotehost:4799/QMS/Service");

                // retrieve a time limited service key

                ServiceKeyClientMessageInspector.ServiceKey = apiClient.GetTimeLimitedServiceKey();

                // get a list of QVS services

                List<ServiceInfo> qvsServices = apiClient.GetServices(ServiceTypes.QlikViewServer);

                if (qvsServices.Count > 0)

                {

                    // retrieve folder settings for the first QVS in the list

                    QVSSettings qvsSettings = apiClient.GetQVSSettings(qvsServices[0].ID, QVSSettingsScope.Folders);

                    // add a new mount

                    qvsSettings.Folders.UserDocumentMounts.Add(new QVSMount() { Browsable = false, Path = @"\\unc\some", Name = "MyMount" });

                    // save settings

                    apiClient.SaveQVSSettings(qvsSettings);

                    Console.WriteLine("Settings saved. New mount added.");

                }

            }

            catch (System.Exception ex)

            {

                Console.WriteLine("An exception occurred: " + ex.Message);

            }

            // wait for user to press any key

            Console.ReadLine();

        }

    }

}

Open the app.config file in your C# project, e.g. by double-clicking on it in Solution Explorer

Depending on whether certificate security is used or not, add one of the the following XML snippets to your app.config file directly within the <system.serviceModel> tag:

CopyC# - Without certificates

<extensions>

    <behaviorExtensions>

        <add name="serviceKeyBehavior" type="MyTestApplication.ServiceKeyBehaviorExtensionElement, MyTestApplication, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>

    </behaviorExtensions>

</extensions>

<behaviors>

    <endpointBehaviors>

        <behavior name="ServiceKeyEndpointBehavior">

            <serviceKeyBehavior/>

        </behavior>

    </endpointBehaviors>

</behaviors>

CopyC# - With certificates

<extensions>

    <behaviorExtensions>

        <add name="serviceKeyBehavior" type="MyTestApplication.ServiceKeyBehaviorExtensionElement, MyTestApplication, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>

    </behaviorExtensions>

</extensions>

<behaviors>

    <endpointBehaviors>

        <behavior name="ServiceKeyEndpointBehavior">

            <serviceKeyBehavior/>

            <clientCredentials>

                <clientCertificate findValue="CN=QVProxy" x509FindType="FindBySubjectDistinguishedName" storeLocation="LocalMachine" storeName="My" />

                <serviceCertificate>

                    <authentication certificateValidationMode="ChainTrust" revocationMode="NoCheck"/>

                </serviceCertificate>            

            </clientCredentials>          

        </behavior>

    </endpointBehaviors>

</behaviors>

Add the following XML attribute to the bottom <endpoint ... /> tag of your app.config file:

CopyC#

behaviorConfiguration="ServiceKeyEndpointBehavior"

Build and run the solution

Below are two examples of complete app.config files:

app.config file not using certificate security

app.config file using certificate security

For use of this see attached.

HTH

André Gomes

agomes1971
Specialist II
Specialist II

Hi,

have you any results yet?

Thanks

André Gomes

Not applicable
Author

Thank you Andre for your incredible level of help and we are doing our best to follow your comprehensive advice

However, we are struggling to precisely follow the step:

Add the following XML attribute to the bottom <endpoint ... /> tag of your app.config file:

CopyC#

behaviorConfiguration="ServiceKeyEndpointBehavior"

We are unsure as to precisely where in the XML of the app.config this attribute needs to go. We have tried placing it within the </endpointBehaviors> tag but this generates an error

Also you mention an attachment at the end of your post but how do we access this attachment?

Thank you