private String getStringToSign(MessageContext msgCtxt) throws Exception {
    String msg = (String) this.properties.get("string-to-sign");
    if (msg == null || msg.equals("")) {
      // by default, get the content of the message (either request or response)
      return msgCtxt.getVariable("message.content");
    }

    // replace ALL curly-braced items in the string-to-sign
    TemplateString ts = new TemplateString(msg);
    Map valuesMap = new HashMap();
    for (String s : ts.variableNames) {
      valuesMap.put(s, msgCtxt.getVariable(s));
    }
    StrSubstitutor sub = new StrSubstitutor(valuesMap);
    String resolvedString = sub.replace(ts.template);
    return resolvedString;
  }
 // If the value of a property value begins and ends with curlies,
 // and contains no spaces, eg, {apiproxy.name}, then "resolve" the
 // value by de-referencing the context variable whose name appears
 // between the curlies.
 private String resolvePropertyValue(String spec, MessageContext msgCtxt) {
   if (spec.startsWith("{") && spec.endsWith("}") && (spec.indexOf(" ") == -1)) {
     String varname = spec.substring(1, spec.length() - 1);
     String value = msgCtxt.getVariable(varname);
     return value;
   }
   return spec;
 }
 private void clearVariables(MessageContext msgCtxt) {
   msgCtxt.removeVariable("hmac.error");
   msgCtxt.removeVariable("hmac.stacktrace");
   msgCtxt.removeVariable("hmac.javaizedAlg");
   msgCtxt.removeVariable("hmac.alg");
   msgCtxt.removeVariable("hmac.string-to-sign");
   msgCtxt.removeVariable("hmac.signature.hex");
   msgCtxt.removeVariable("hmac.signature.b64");
 }
  public ExecutionResult execute(MessageContext msgCtxt, ExecutionContext exeCtxt) {
    try {
      clearVariables(msgCtxt);
      String signingKey = getKey(msgCtxt);
      String stringToSign = getStringToSign(msgCtxt);
      String algorithm = getAlgorithm(msgCtxt);
      boolean debug = getDebug(msgCtxt);
      msgCtxt.setVariable("hmac.alg", algorithm);

      String javaizedAlg = javaizeAlgorithmName(msgCtxt, algorithm);
      if (debug) {
        msgCtxt.setVariable("hmac.javaizedAlg", javaizedAlg);
      }

      Mac hmac = Mac.getInstance(javaizedAlg);
      SecretKeySpec key = new SecretKeySpec(signingKey.getBytes(), javaizedAlg);
      hmac.init(key);
      byte[] hmacBytes = hmac.doFinal(stringToSign.getBytes("UTF-8"));
      String sigHex = Hex.encodeHexString(hmacBytes);
      String sigB64 = Base64.encodeBase64String(hmacBytes);

      if (debug) {
        msgCtxt.setVariable("hmac.key", signingKey);
      }
      msgCtxt.setVariable("hmac.string-to-sign", stringToSign);
      msgCtxt.setVariable("hmac.signature.hex", sigHex);
      msgCtxt.setVariable("hmac.signature.b64", sigB64);

      // presence of hmac-base64 property indicates verification wanted
      String expectedHmac = getHmac(msgCtxt);
      if (expectedHmac != null) {
        if (!sigB64.equals(expectedHmac)) {
          msgCtxt.setVariable("hmac.error", "HMAC does not verify");
          return ExecutionResult.ABORT;
        }
      }
    } catch (Exception e) {
      msgCtxt.setVariable("hmac.error", e.getMessage());
      msgCtxt.setVariable("hmac.stacktrace", ExceptionUtils.getStackTrace(e));
      return ExecutionResult.ABORT;
    }
    return ExecutionResult.SUCCESS;
  }