---
title: Node class
description: Implement the Node interface to create custom authentication nodes that access shared state, request user input through callbacks, and define exit paths in PingAM authentication trees
component: pingam
version: 7.5
page_id: pingam:auth-nodes:core-class
canonical_url: https://docs.pingidentity.com/pingam/8.1/auth-nodes/core-class.html
llms_txt: https://docs.pingidentity.com/pingam/llms.txt
docs_for_agents: https://developer.pingidentity.com/build-with-ai/docs-for-agents.md
keywords: ["Extensibility", "Nodes &amp; Trees", "Scripts"]
superseded_by: https://docs.pingidentity.com/pingam/8.1/auth-nodes/core-class.html
---

# Node class

The `Node` class can access and modify the persisted state shared between the nodes within a tree, and can request input by using callbacks. The class also defines the possible exit paths from the node.

In Java terms, an authentication node is a class that implements the `Node` interface, `org.forgerock.openam.auth.node.api.Node`.

The `SetSessionProperties` class shows the steps to implement the Node interface:

```java
package org.forgerock.openam.auth.nodes;

import java.util.Map;

import javax.inject.Inject;

import org.forgerock.openam.annotations.sm.Attribute;
import org.forgerock.openam.auth.node.api.Action;
import org.forgerock.openam.auth.node.api.Node;
import org.forgerock.openam.auth.node.api.SingleOutcomeNode;
import org.forgerock.openam.auth.node.api.TreeContext;
import org.forgerock.openam.auth.nodes.validators.SessionPropertyValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.inject.assistedinject.Assisted;

/*
 * A node that defines a configurable set of properties to add to
 * the user's session if/when it is created.
 */
@Node.Metadata(outcomeProvider = SingleOutcomeNode.OutcomeProvider.class,
        configClass = SetSessionPropertiesNode.Config.class,
        tags = {"utilities"})                                           1
public class SetSessionPropertiesNode extends SingleOutcomeNode {       2

  /
   * Configuration for the node.
   /
  public interface Config {                                             3
    /
     * A map of property name to value.
     * @return a map of properties.
     /
    @Attribute(order = 100, validators = SessionPropertyValidator.class)
    Map<String, String> properties();
  }

  private final Config config;                                          4
  private final Logger logger = LoggerFactory.getLogger("SetSessionPropertiesNode.class");

  /
   * Constructs a new SetSessionPropertiesNode instance.
   * @param config Node configuration.
   */
  @Inject                                                               5
  public SetSessionPropertiesNode(@Assisted Config config) {
    this.config = config;
  }

  @Override
  public Action process(TreeContext context) {                          6
    logger.debug("SetSessionPropertiesNode started");
    Action.ActionBuilder actionBuilder = goToNext();
    config.properties().entrySet().forEach(property → {
      actionBuilder.putSessionProperty(property.getKey(), property.getValue());
      logger.debug("set session property {}", property);
    });
    return actionBuilder.build();
  }
}
```

| Step                                    | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | Further information                                                                                                                                                                                                                                                                                                                    |
| --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 Apply the `@Node.Metadata` annotation | The *annotation* specifies the outcome provider, configuration class, and optionally, the configuration validation class and tags.Use an existing outcome provider such as `SingleOutcomeNode.OutcomeProvider` or `AbstractDecisionNode.OutcomeProvider`, or create a custom provider and reference the class from the annotation.                                                                                                                                                                                                                                                       | [Metadata annotation](core-metadata.html)                                                                                                                                                                                                                                                                                              |
| 2 Implement the `Node` interface        | Extend one of the following abstract classes to implement the `Node` interface:- `SingleOutcomeNode`

  For nodes with a single exit path; for example [Modify Auth Level node](https://docs.pingidentity.com/auth-node-ref/7.5/modify-auth-level.html).

- `AbstractDecisionNode`

  For nodes with a boolean-type exit path (true/false, allow/deny); for example, [Data Store Decision node](https://docs.pingidentity.com/auth-node-ref/7.5/data-store-decision.html).Alternatively, write your own implementation of the `Node` interface to define custom exit paths.              | Javadoc:- [Node](../_attachments/apidocs/org/forgerock/openam/auth/node/api/Node.html) interface

- [AbstractDecisionNode](../_attachments/apidocs/org/forgerock/openam/auth/node/api/AbstractDecisionNode.html) class

- [SingleOutcomeNode](../_attachments/apidocs/org/forgerock/openam/auth/node/api/SingleOutcomeNode.html) class |
| 3 Implement the `Config` interface      | The `Config` interface defines the configuration data for a node.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | [Config interface](core-config.html)                                                                                                                                                                                                                                                                                                   |
| 4 Define private constants and methods  | *Optional*                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |                                                                                                                                                                                                                                                                                                                                        |
| 5 Inject dependencies                   | Inject objects using Guice as this makes it easier to unit test your node.This example specifies `config` as a parameter. You can also include supported AM classes, instances of third-party dependencies, or your own types.                                                                                                                                                                                                                                                                                                                                                           | [Inject objects into a node instance](core-inject.html).                                                                                                                                                                                                                                                                               |
| 6 Override the `process` method         | The `process` method is where you store and retrieve state if required.It takes a `TreeContext` parameter that you can use to access the request, callbacks, shared state and other input.The method returns an `Action` object. This can be a response of callback to the user, an update of state, or a choice of outcome. The `Action` object encapsulates changes to state and flow control.The choice of outcome in a simple decision node would be `true` or `false`, resulting in the authentication tree flow moving from the current node to a node at the relevant connection. | [Action class](core-action.html).                                                                                                                                                                                                                                                                                                      |
