No announcement yet.

Velocity and Source

  • Filter
  • Time
  • Show
Clear All
new posts

  • Velocity and Source


    To dynamically define the parameters/settings of the Source connector, for example a directory for a file drive, it is possible to use a Velocity variable.
    Only the "Deploy" script can be executed/can run before the Source connector.
    This means that the Velocity variable can only be initialized with a GlobalMap or a GlobalChannelMap.
    Is there another way to initialize a Velocity variable defined/used in a Source connector before the Source connector has run?

    Thank you for your answer :-)

  • #2
    Yes, in the pre-processor script


    • #3
      Thank you for the answer. But I disagree :-)

      In the documentation : Preprocessor Script: This runs once for every message, after the source connector sends a message to the channel.

      For example. Let's say that the Directory setting of the Source connector (a File Reader) is defined with ${MySourceDirectory} Velocity variable.
      If ${MySourceDirectory} is set in the preprocessor, it will not work.
      The source connector, which is a File Reader, does not know where to look for the file(s) because ${MySourceDirectory} is not defined.
      Thus, the file(s) that could be found by the Source Connector are not detected because the Directory setting is not defined.
      The consequence is that no message will be generated to the pre-processor, so ${MySourceDirectory} is never defined.

      Please let me know if this is not clear enough and/or if this is not correct.


      • #4
        You are correct that the preprocessor will not run until after a message has already been retrieved. If you set 'MySourceDirectory' in the globalChannelMap in the deploy script, the preprocessor (or transformer, postprocessor, etc...) could modify that value in the globalChannelMap for the next run.

        Velocity can also call methods of Java objects that may return dynamic values.

        What are you trying to accomplish?


        • #5
          The main objective is the following :

          Easily take the channels defined in our Test environment and deploy them in the Production environment.

          The main differences between the Test and Production environments are the Velocity variables defined in the different Source/Destination connectors as well as the variables used in the different filters/transformers.
          The idea is to call a web service when the channel is deployed.
          The input of the web service is the server ID and the channel ID.
          The web service will provide the values of the different Velocity variables.

          The annoying point is the following :

          Channel 1 defines a Directory setting with the Velocity variable : ${Directory}
          A channel 2 defines a Directory setting with the same Velocity variable : ${Directory}.
          Both must be defined at a GlobalMap or GlobalChannelMap level.
          Therefore they cannot be distinguished (it would not be the case on a channel level). This is a problem.
          I know one solution would be to use different variable names, for example ${Directory1} and ${Directory2}.
          But this will be a complex process if several developers are working in parallel on different channels.
          What would be the rule for naming the different Velocity variables in this case to make sure they have different names?
          I prefer there is no rule and the variables are 'defined' on the Channel level.

          I hope the explanation is clear. I am trying to find a solution for that issue.
          Last edited by boukenka; 05-21-2020, 05:06 AM.


          • #6
            I think it sounds like you already have a solution?

            If you want the variables to be defined at the channel level, load your configuration in the deploy script and store in the globalChannelMap. There should be no conflict between channels using the same map keys.

            How do you imagine returning the values? A single object in JSON? You can actually put a javascript object in the map and access the properties from velocity.
            var resultJSON = callWebService(serverName, channelId);
            var parsedJSON = JSON.parse(resultJSON);
            $gc('config', parsedJSON);
            Then in your connector you could use ${config.Directory}.

            Or if you want each config var directly added to the globalChannelMap
            // javascript object can be seen as a java.lang.Map when passing to a java method
            Be careful storing numbers to be used with velocity. All javascript numbers are converted to java.lang.Double when accessed by Java. Velocity does string replacement. It will often unintentionally add a '.0' to the end of your integer values that are stored as numbers when converting to a string. It's better to store your numbers as strings if they are to be used with velocity.

            If you use the configurationMap (which does not sound appropriate for your use case) it enforces this by only allowing string values to be stored.


            • #7
              Thank you for taking the time to write this long answer and for giving me advice. I really appreciate it.

              There is one point I don't understand in your answer: There should be no conflict between channels using the same map keys.

              Maybe my explanation was not clear. Or maybe I didn't understand your answer correctly.

              A channel 1 defines a directory parameter with the Velocity variable: ${config.Directory} This variable should have the value "/tmp/directory1".
              A channel 2 defines a directory parameter with the Velocity variable: ${
              config.Directory} This variable should have the value "/tmp/directory2".

              If the variable ${config.Directory} Velocity variable is defined in the globalChannelMap, only one value may be possible for ${config.Directory}: "/tmp/directory1" or '"/tmp/directory2".
              It cannot be both. Unless ${config.Directory} is set at the channel level. Is this correct? That's what I would like to get.

              Sorry if I seem to be repeating myself with my question.
              Last edited by boukenka; 05-21-2020, 01:29 PM.


              • #8
                You are correct that you could only define it once if using the globalMap, but using the globalChannelMap is setting it at the channel level. Each channel has its own globalChannelMap, just like each message has its own channelMap.

                There is a section in the user guide that explains the scope and purpose of each of the Mirth maps.


                • #9
                  You are right.

                  Thank you for your help.

                  Have a good weekend !