Service Interceptor Guide

Is anyone aware of a guide to writing service interceptors?  I have the REST API Documentation which has a small section, but really looking for information on what references I need to include, how to setup the development environment, any actions such as user authentication that need to be completed?

A HelloWorld interceptor tutorial that goes through these would be so helpful if anyone has one...

  • Hi Simon,

     

    I just wanted to chime in and say that I would be very interested in this as well!! We have at least one fairly immediate situation where a service interceptor might be very helpful.

     

    Thanks,

    David

     

    From: Tessitura Technical Forum [mailto:forums-technical@tessituranetwork.com] On Behalf Of Simon Davidson
    Sent: Wednesday, August 29, 2012 1:53 AM
    To: David Frederick
    Subject: [Tessitura Technical Forum] Service Interceptor Guide

     

    Is anyone aware of a guide to writing service interceptors?  I have the REST API Documentation which has a small section, but really looking for information on what references I need to include, how to setup the development environment, any actions such as user authentication that need to be completed?

    A HelloWorld interceptor tutorial that goes through these would be so helpful if anyone has one...




    This message was sent automatically to you by www.tessituranetwork.com because you subscribed to the Tessitura Technical Forum. You may reply to this message to post to the Technical forum or visit the site to search, read and post to the forums. In the interest of keeping the forum posts from becoming cluttered, we encourage you to delete previous message text from your reply before sending. Thank you!

  • Hello - I'd like to third that request!

  • Former Member
    Former Member $organization in reply to Nicholas Hudson-Ellis (Past Staff Member)

    We are working on having a few plug-in examples and some basic getting started level documentation ready to go along with the 11.0.4 release coming out soon.

  • That's great news!

    Any planned release dates for 11.04 yet? :-)

  • That's great Ron!  Thanks for the update...

  • Former Member
    Former Member $organization

    Scoll to page 36 in this PDF:

     

    http://www.tessituranetwork.com/tlcc/2012/PDFs/03-B_Version_11_Alchemy.pdf

     

    for the slideshow from Jon Ballinger's presentation on Interceptors from TLCC2012. It lacks some key details but it's a start.

    RE: the "Plugin Layer": To find it, do a search for all the 'plugins' folders on your Tessitura Services server. Each service folder has its own 'plugins' subfolder, containing the 'PluginConfig.xml' file. Interceptor config XML code goes in between the tags <PluginConfigs> and </PluginConfigs> .

    Now if we could find some docs on developing and loading a Tessitura dll assembly in a language like vb.NET, we'd be in business. Anybody got an example?

    Here's a text version of the Constituent plugin configuration image from the TLCC presentation, for cut/paste purposes (save you a few keystrokes, maybe):

    <PluginConfig>
     <UriMarch>Constituents/Search/* </UriMarch>
     <Verb>Get </Verb>
     <FullPluginName>ConstituentService.Search</FullPluginName>
     <PluginPlacement>POST</PluginPlacement>
    </PluginConfig> 

    The other plugin configs follow the same XML format.

    I hope this helps somehow . . . .

  • Hi Ron,

    Has the service interceptor examples and documentation you referred to been posted? I didn't see it in the 11.0.4 documentation and haven't been able to find it.

    Thanks,
    David 

  • Hi Everyone,

    After much turmoil we finally managed to implement a “Hello world” interceptor that just writes a text file to hard drive. I hope it helps someone.

    1.     Start a new class library project in VS and name it TestPluginCSharp.

    2.     Copy Tessitura.Services.Common.Interceptor.Client.dll from your Tessitura service (the one that you are building plug-in for e.g. ConstituentService) bin folder to your new class library bin folder and add project reference to it.

    3.     Add a class named TestPluginCSharp and add the following code:

     

    using Tessitura.Services.Common.Interceptor.Client;

     namespace TestPluginCSharp

    {

        public class TestPluginCSharp

        {

            public static PluginData Operation(PluginData pluginData)

            {

                //you'll need the folder set up somewhere on the server for your test file

                System.IO.File.WriteAllText(@"C:\Test\test.txt", "Howdy!");

     

                return pluginData;

            }

        }

    }

    4.     Build your project

    5.     Copy TestPluginCSharp.dll from bin\Debug folder to the service Plugins folder (e.g. ConstituentService\Plugins).

    6.     Open PluginConfig.xml from ConstituentService\Plugins in your VS and add:

    <PluginConfigs>

      <PluginConfig>

        <UriMatch>Constituents/*</UriMatch>

        <Verb>GET</Verb>

        <FullPluginName>TestPluginCSharp.TestPluginCSharp</FullPluginName>

        <PluginPlacement>PRE</PluginPlacement>

      </PluginConfig>

    </PluginConfigs>

     

    Note: no preceding forward slash in UriMatch

     

    7.       Save PluginConfig

    8.       You may need to restart Application Pool for Tess in IIS

    9.       I also have EnablePlugins and ReloadPluginConfig keys set to true in Web.config of the service.

    10.   In Firefox start RESTClient. Set up OAuth Authorisation as per REST_API_Documentation.doc

    11.   Set call method to GET

    12.   Set to address of your service (e.g. https://your_server/Tess/ConstituentService/Constituents/60671061 ) and send request.

    13.   This should result in test.txt being written to the path at step 2.

     

    Good luck!

     

    Sergei Stenkov

  • Hi Sergei,

    That's a great help, thanks very much!

    I don't suppose you've experimented a bit further and tried to get information from the REST Service?  So in your example, how you would get the consitutent id 60671061.

    Thanks

  • Former Member
    Former Member $organization

    Sergei

     

    Thanks a lot for this information. We managed to get something working with a lot of trial an error, but this short list of steps will help us get rid of a lot of extra tasks that we did while we were trying to get things to work (ie. throwing punches in the dark). This is very helpful.

     

    Fernando Margueirat
    Business Analyst
    The National Ballet of Canada
    470 Queens Quay West
    Toronto, Ontario
    M5V 3K4
    P: 416 345 9686 x453
    F: 416 345 8323

     

     

     

    From: Tessitura Technical Forum [mailto:forums-technical@tessituranetwork.com] On Behalf Of Sergei Stenkov
    Sent: October-25-12 1:19 AM
    To: Fernando Margueirat
    Subject: Re: [Tessitura Technical Forum] Service Interceptor Guide

     

    Hi Everyone,

    After much turmoil we finally managed to implement a “Hello world” interceptor that just writes a text file to hard drive. I hope it helps someone.

    1.     Start a new class library project in VS and name it TestPluginCSharp.

    2.     Copy Tessitura.Services.Common.Interceptor.Client.dll from your Tessitura service (the one that you are building plug-in for e.g. ConstituentService) bin folder to your new class library bin folder and add project reference to it.

    3.     Add a class named TestPluginCSharp and add the following code:

     

    using Tessitura.Services.Common.Interceptor.Client;

     namespace TestPluginCSharp

    {

        public class TestPluginCSharp

        {

            public static PluginData Operation(PluginData pluginData)

            {

                //you'll need the folder set up somewhere on the server for your test file

                System.IO.File.WriteAllText(@"C:\Test\test.txt", "Howdy!");

     

                return pluginData;

            }

        }

    }

    4.     Build your project

    5.     Copy TestPluginCSharp.dll from bin\Debug folder to the service Plugins folder (e.g. ConstituentService\Plugins).

    6.     Open PluginConfig.xml from ConstituentService\Plugins in your VS and add:

    <PluginConfigs>

      <PluginConfig>

        <UriMatch>Constituents/*</UriMatch>

        <Verb>GET</Verb>

        <FullPluginName>TestPluginCSharp.TestPluginCSharp</FullPluginName>

        <PluginPlacement>PRE</PluginPlacement>

      </PluginConfig>

    </PluginConfigs>

     

    Note: no preceding forward slash in UriMatch

     

    7.       Save PluginConfig

    8.       You may need to restart Application Pool for Tess in IIS

    9.       I also have EnablePlugins and ReloadPluginConfig keys set to true in Web.config of the service.

    10.   In Firefox start RESTClient. Set up OAuth Authorisation as per REST_API_Documentation.doc

    11.   Set call method to GET

    12.   Set to address of your service (e.g. https://your_server/Tess/ConstituentService/Constituents/60671061 ) and send request.

    13.   This should result in test.txt being written to the path at step 2.

     

    Good luck!

     

    Sergei Stenkov

    From: Simon Davidson <bounce-simondavidson9902@tessituranetwork.com>
    Sent: 8/29/2012 3:45:10 AM

    Is anyone aware of a guide to writing service interceptors?  I have the REST API Documentation which has a small section, but really looking for information on what references I need to include, how to setup the development environment, any actions such as user authentication that need to be completed?

    A HelloWorld interceptor tutorial that goes through these would be so helpful if anyone has one...




    This message was sent automatically to you by www.tessituranetwork.com because you subscribed to the Tessitura Technical Forum. You may reply to this message to post to the Technical forum or visit the site to search, read and post to the forums. In the interest of keeping the forum posts from becoming cluttered, we encourage you to delete previous message text from your reply before sending. Thank you!

  • Hi Simon,

    It's all baby steps for me with interceptors. You could search for it I think. When I try executing this search through the REST client it brings back ConstituentSummary containing the ID:

    https://tessxxx.xxx.com/Tess/ConstituentService/Constituents/Search?q=""&type=basic&constituentGroups=individuals&ln=stenkov

    ... and a bit of result:

     

    <City>SYDNEY</City>
    <ConstituentGroup>1</ConstituentGroup>
    <ConstituentType>1</ConstituentType>
    <Country>Australia</Country>
    <FirstName>Sergei</FirstName>
    <ForSort>Stenkov/Sergei</ForSort>
    <FullNameAlias/>
    <Id>60671314</Id>

    You can get the list of resources for the service at address that looks something like:
    https://tessxxx.xxx.com/Tess/ConstituentService
    I am trying to modify the returned data in the interceptor at the moment. I can modify it and save it on the server but when I try to return modified data, it actually returns the original data. Probably just need to figure out how to work with Xml.Linq properly.

     



    [edited by: Sergei Stenkov at 5:06 PM (GMT -6) on 25 Oct 2012]
  • Hi All,

    Good day.

    Is there any one have a clear ideas about how to set up the plugin configurations?

    it is not hard to write .net code, it is not hard to test the .net code.

    But finally when I put the custom plugins into the REST, it is very hard to figure out where when and what is happening.

    from user point view, things are clear, like 1, if someone already had a mobile in the system, stop insert same mobile number, 2, or stop same email address entry.

    The REST API document is missing the detail how client calls REST.

    also there is something not in the document. what is RegEx? like this:

    2014-12-09 16:30:44.3753|Debug|Verb and Placement matched but RegEx for URI match '^CRM/Constituents/[^/]*/Snapshot(/)?$' didn't match the actual URI 'ReferenceData/SystemDefaults/Summary'.

    I can see the REST structure is very complicated.

    is there some documents about this part of REST?

    have fun

    Ben

     

     

     

  • $organization in reply to Ben Gu

    HI All,

    Good day.

    is there anyone can tell me why same codes worked with "POST" method (insert) didn't work with "PUT" method(update)?

    is there something different inside REST between "POST" URI and "PUT" URI?

    Thank you very much for your help.

    have fun

    Ben

  • $organization in reply to Ben Gu

    namespace MTC_REST.TessituraPlugins.ConstituentService
    {
        public class DupEmailLoginPreventionSnapshot
        {
            public static PluginData Operation(PluginData input)
            {
                string update = string.Empty;
                string insert = string.Empty;
                update = @"PUT";
                insert = @"POST";
                if (input.Verb == insert)
                {
                    var constituent = SerializationHelper.Deserialize<ConstituentSnapshot>(input.Data);
                    var myEmail = input.Data;
                    if (myEmail.Name.ToString().ToLower().Contains("electronicaddress"))
                    {
                        string EmailAddress = string.Empty;
                        int mycheck = 0;
                        EmailAddress = constituent.ElectronicAddress.Address.ToString();
                        mycheck = checkEmail(EmailAddress);
                        if (mycheck > 0)
                        {
                            throw new PluginValidationException("Email Address is already under another account " + mycheck.ToString() + ". It is not allowed for this account.");
                        }
                    }
                    return input;
                }

                else if (input.Verb == update)///this part codes have the same logic but it never hit by plugin.
                {
                    var constituentUpdate = SerializationHelper.Deserialize<ConstituentSnapshot>(input.Data);
                    var myEmailUpdate = input.Data;
                    if (myEmailUpdate.Name.ToString().ToLower().Contains("electronicaddress"))
                    {
                        string EmailAddress = string.Empty;
                        int mycheck = 0;
                        EmailAddress = constituentUpdate.ElectronicAddress.Address.ToString();
                        mycheck = checkEmail(EmailAddress);
                        if (mycheck > 0)
                        {
                            throw new PluginValidationException("Email Address is already under another account " + mycheck.ToString() + ". It is not allowed for this account.");
                        }
                    }

                    return input;
                }
                else
                {
                    return input;
                }
            }

            public static int checkEmail(string emailaddress)
            {

                string tmp = string.Empty;
                int myreturn = 0;
                var sqlCommandHelper = new SqlCommandHelper();
                var sqlStatement = "dbo.LP_MTC_INTERCEPTION_STOP_EMAIL_LOGIN_DUP";
                var parameters = new Dictionary<string, string>();
                parameters.Add("@EMAILADDRESS", emailaddress);
                System.Data.DataSet ds=  sqlCommandHelper.ExecuteSqlCommandReturnDataSet(sqlStatement, parameters, true);
                System.Data.DataTable tb = ds.Tables[0];
                if (tb.Rows.Count>0)
                {
                    tmp = tb.Rows[0]["customer_no"].ToString();
                }
                if (tmp.Trim().Length > 0)
                {
                    myreturn =Convert.ToInt32( tmp.Trim().ToString());
                }
                return myreturn;
            }
        }
    }