All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nstream.adapter.common.relay.Directive Maven / Gradle / Ivy

There is a newer version: 4.15.23
Show newest version
// Copyright 2015-2024 Nstream, inc.
//
// Licensed under the Redis Source Available License 2.0 (RSALv2) Agreement;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://redis.com/legal/rsalv2-agreement/
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package nstream.adapter.common.relay;

import swim.api.agent.AgentContext;
import swim.structure.Item;
import swim.structure.Value;
import swim.util.Log;

/**
 * An environment frame from an in-progress interpretation of a program written
 * in the message relay domain-specific language (DSL).
 * 

{@code Directive} evaluation may create "child" {@code Directives} * or require state from "ancestor" frames. * *

Illustrative Example

* * Consider the following DSL snippet: * *
{@code
 * {
 *   @command($code) {
 *     nodeUri: "/healthcheck",
 *     laneUri: "payloadStatusCode"
 *   },
 *   @foreach($rates.*) {
 *     @command {
 *       complexNodeUri: {
 *         "/currency/",
 *         @substring($*:){lower:3}
 *       },
 *       laneUri:"addEvent",
 *       value: $:*
 *     }
 *   }
 * }
 * }
* * and the following top-level input (JSON): * *
{@code
 * {
 *   "code": 200,
 *   "rates": {
 *     "USDEUR": {
 *       "rate": 0.967715,
 *       "timestamp": 1660235884
 *     },
 *     "USDJPY": {
 *       "rate": 132.716501,
 *       "timestamp": 1660235884
 *     }
 *   }
 * }
 * }
* * Evaluating the snippet against the input yields two top-level actions to * evaluate sequentially: *
    *
  1. Send a WARP command with {@code nodeUri="/healthcheck"}, {@code * laneUri="payloadStatusCode", value=200} *
  2. For each {@code Item} {@code rate} in {@code input.get("rates")}, send * a WARP command with {@code nodeUri="/currency/"+rate.key().substring(3)}, * {@code laneUri="addEvent", value=rate.value()} *
* These correspond the following directives: *
    *
  1. A {@link Take} that trims {@code input} to {@code 200} before * passing it to its child directive, which is a {@code Command} *
  2. A {@code Take} that trims {@code input} to {@code input.get("rates")} * before passing it to its child directive, which is a {@link ForEach} that * passes on each of the two items in the aforementioned truncation to a * different child directive, each of which is a {@link Command} whose {@code * complexNodeUri} can only be evaluated with a {@link Substring}'s help *
* for a total of 8 directives spawned. * * @param the possibly-Absent return type of {@code evaluate}-ing this {@code * Directive} */ public abstract class Directive { protected final Directive parent; protected final AgentContext context; protected final Log log; protected final Item scope; public Directive(Directive parent, AgentContext context, Log log, Item scope) { this.parent = parent; this.context = context; this.log = log; this.scope = scope; } /** * Evaluates this {@code Directive} against {@link #scope}, possibly spawning * and recursively evaluating more {@code Directives}. * * @return the result of evaluating this {@code Directive} */ public abstract T evaluate() throws InterpretException; final String hintOrLiteralToString(Value hint, Value literal, String prefix) { return hintOrLiteralToString(hint, literal, prefix, false); } final String hintOrLiteralToString(Value hint, Value literal, String prefix, boolean isFirst) { if (isFirst) { boolean didFindHint = false; String result = ""; if (hint != null && !hint.isDefined()) { didFindHint = true; result += (prefix + "=" + hint); } result += (literal == null || !literal.isDefined() ? "" : ((didFindHint ? ", " : "") + prefix + "Literal=" + literal)); return result; } else { return (hint != null && hint.isDefined() ? (", " + prefix + "=" + hint) : "") + (literal != null && literal.isDefined() ? (", " + prefix + "Literal=" + literal) : ""); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy