text:
/** @jsx adapter.createNode */
import expect from 'expect';
import { parse, stringify, map, reduce, adapter } from '../src/index';
import { count, inspect, noop, XHTML_NAMESPACE } from './test_utilities';

describe('dom transformation methods', function () {
  const LIST_ITEM = '<li';
  const COMMENT = 'comment node';
  const TEXT_ONE = 'first text node';
  const TEXT_TWO = 'second text node';

  /**
   * Creates a dom containing text, comment and element nodes -
   *
   *
   *  first text node
   *

   *    second text node
   *

   *
   * @returns {Object} a dom
   */
  function createModel() {
    const dom = adapter.createDocumentFragment();
    const d = adapter.createElement('div', XHTML_NAMESPACE, []);
    adapter.appendChild(dom, adapter.createCommentNode(COMMENT));
    adapter.appendChild(dom, adapter.createTextNode(TEXT_ONE));
    adapter.appendChild(d, adapter.createTextNode(TEXT_TWO));
    adapter.appendChild(dom, d);

    return dom;
  }

  /**
   * Creates a dom where the `id` attributes of nodes are `1`
   * based indexes in the tree, with the exception of the root
   * not, which is indexed as `0`.
   *
   *

   *

   *

   *

   *

   *

   *

   *

   *
   * @returns {Object} an indexed dom
   */
  function createIndexedModel() {
    const indexed = adapter.createDocumentFragment();
    const container = adapter.createElement(
      'div',
      XHTML_NAMESPACE,
      [{ name: 'id', value: '0.1' }],
    );
    adapter.appendChild(indexed, container);

    // An unordered list.
    const ul = adapter.createElement('ul', XHTML_NAMESPACE, [{ name: 'id', value: '0.1.1' }]);
    ['0.1.1.1', '0.1.1.2', '0.1.1.3'].forEach(function (i) {
      const li = adapter.createElement('li', XHTML_NAMESPACE, [{ name: 'id', value: i }]);
      adapter.appendChild(ul, li);
    });
    adapter.appendChild(container, ul);

    // A paragraph tag.
    const p = adapter.createElement('p', XHTML_NAMESPACE, [{ name: 'id', value: '0.1.2' }]);
    adapter.appendChild(container, p);

    return indexed;
  }

  describe('map', function () {
    it('is intended to be partially applied for composition', function () {
      const mapper = map.bind(null, noop);
      expect(mapper).toBeA('function');
    });

    /**
     * TODO: These tests are also completely broken for some reason.
     * Drunk, will sort in the morning - possibly better to just test
     * the exported `map` and `reduce` functions first.
     */
    describe('partially applied map', function () {
      it('should pass cloned and detached nodes to the callback', function () {
        let calls = 0;
        /**
         * @param {Function}
         * @param {Object}
         *
         * @returns {Object}
         */
        function fn(node) {
          expect(node.next).toBe(null);
          expect(node.prev).toBe(null);
          expect(adapter.getParentNode(node)).toBe(null);

          calls++;
          return node;
        }

        const mapper = map.bind(null, fn);
        const dom = createModel();

        mapper(dom);
        expect(calls).toBe(5);
      });

      it('should traverse the dom in the correct order', function () {
        /**
         * NOTE: These tests are wrapped for scoping reasons.
         * I'm to lazy to come up with multiple coherant
         * variable names.
         *
         * The first IIFE tests recursion in a simple dom.
         */
        (function () {
          const types = [];

          /**
           * Unshifts traversed node types into an array.
           *
           * @param {Object}
           *
           * @returns {Object}
           */
          function fn(node) {
            types.unshift(node.type);
            return node;
          }

          const dom = createModel();

          // Create a mapper using `.bind` for partial application.
          const mapper = map.bind(null, fn);
          const mapped = mapper(dom);

          // This would be the opposite order into which the dom was recursed.
          expect(types).toEqual(['root', 'comment', 'text', 'tag', 'text']);

          // Ensure that there wasn't any mutation in the model, but noop worked.
          expect(dom).toNotBe(mapped);
          expect(inspect(dom)).toBe(inspect(mapped));
          expect(stringify(dom)).toBe(stringify(mapped));
        }());

        /**
         * This is designed to test the recursion order of an indexed
         * dom, and further establishes that no mutation is occuring.
         */
        (function () {
          const ids = [];

          /**
           * Unshifts traversed node types into an array.
           *
           * @param {Object}
           *
           * @returns {Object}
           */
          function fn(node) {
            if (adapter.isElementNode(node)) {
              const value = adapter.getAttrList(node)[0].value;
              ids.unshift(value);
            }

            return node;
          }

          const dom = createIndexedModel();

          // Create a mapper using `.bind` for partial application.
          const mapper = map.bind(null, fn);
          const mapped = mapper(dom);

          // This would be the opposite order into which the dom was recursed.
          expect(ids).toEqual([
            '0.1',
            '0.1.1',
            '0.1.1.1',
            '0.1.1.2',
            '0.1.1.3',
            '0.1.2',
          ]);

          // Ensure that there wasn't any mutation in the model, but noop worked.
          expect(dom).toNotBe(mapped);
          expect(inspect(dom)).toBe(inspect(mapped));
          expect(stringify(dom)).toBe(stringify(mapped));
        }());
      });

      /**
       * NOTE: Special case - return a single text child in array
       * appears to be broken.
       *
       * SEE: `https://github.com/raywhite/office-sites/issues/889`
       */
      it('should handle a single text node child', function () {
        const markup = 'text';

        const model = parse(markup);
        (function () {
          function fn(node) {
            if (adapter.isElementNode(node)) {
              const children = adapter.getChildNodes(node);
              return children;
            }

            return node;
          }

          const mapper = map.bind(null, fn);
          const mapped = mapper(model);
          const child = adapter.getChildNodes(mapped)[0];
          expect(adapter.isTextNode(child)).toBe(true);
          expect(adapter.getTextNodeContent(child)).toBe('text');
          expect(stringify(mapped)).toBe('text');
        }());

        (function () {
          function ChildReplacer(props) { // eslint-disable-line no-unused-vars
            const { children } = props;
            return children;
          }

          function fn(node) {
            if (adapter.isElementNode(node)) {
              return <ChildReplacer>{adapter.getChildNodes(node)}</ChildReplacer>;
            }

            return node;
          }

          const mapper = map.bind(null, fn);
          const mapped = mapper(model);
          const child = adapter.getChildNodes(mapped)[0];
          expect(adapter.isTextNode(child)).toBe(true);
          expect(adapter.getTextNodeContent(child)).toBe('text');
          expect(stringify(mapped)).toBe('text');
        }());
      });

      it('should correctly remove nodes where null is returned', function () {
        /**
         * NOTE: Encapsulated for the same reason as above.
         *
         * The first set just removes all text nodes from the dom.
         */
        (function () {
          /**
           * Returns the clone unless we are dealing with a text node,
           * in which case we return null.
           *
           * @param {Object}
           *
           * @returns {Object}
           */
          function fn(node) {
            if (adapter.isTextNode(node)) {
              return null;
            }

            return node;
          }

          const dom = createModel();
          const mapper = map.bind(null, fn);

          const mapped = mapper(dom);

          const re = /type: 'text'/;

          // Ensure that the new dom contains no text nodes.
          expect(dom).toNotBe(mapped);
          expect(inspect(dom)).toMatch(re);
          expect(inspect(mapped)).toNotMatch(re);
          expect(stringify(dom)).toNotBe(stringify(mapped));
          expect(stringify(dom).length).toBeGreaterThan(stringify(mapped).length);
        }());

        /**
         * This test removes all list items and keeps a count of
         * removed nodes.
         */
        (function () {
          /**
           * Removes any node that is a list item or noops.
           *
           * @param {Object}
           *
           * @returns {Object}
           */
          function fn(node) {
            if (adapter.isElementNode(node) && adapter.getTagName(node) === 'li') {
              return null;
            }

            return node;
          }

          const dom = createIndexedModel();
          const mapper = map.bind(null, fn);

          const mapped = mapper(dom);

          // Ensure that the new dom contains no text items.
          expect(dom).toNotBe(mapped);
          expect(inspect(dom).length).toBeGreaterThan(inspect(mapped).length);
          expect(count(stringify(dom), LIST_ITEM)).toBe(3);
          expect(count(stringify(mapped), LIST_ITEM)).toBe(0);
        }());
      });

      it('should correctly replace nodes where a single node is returned', function () {
        const INJECTED = 'injected text node';
        /**
         * Return the original node, unless;
         *    - The node is a list item (append a text node).
         *    - The node is a paragraph (switch for and article)
         *
         * @param {Object}
         *
         * @returns {Object}
         */
        function fn(node) {
          if (adapter.isElementNode(node)) {
            const tagName = adapter.getTagName(node);
            if (tagName === 'li') {
              const textNode = adapter.createTextNode(INJECTED);
              adapter.appendChild(node, textNode);
              return node;
            }

            if (tagName === 'p') {
              const article = adapter.createElement('article', XHTML_NAMESPACE, []);
              return article;
            }
          }

          return node;
        }

        const dom = createIndexedModel();
        const mapper = map.bind(null, fn);

        const mapped = mapper(dom);

        // Ensure that the new dom contains three text nodes.
        expect(dom).toNotBe(mapped);
        expect(count(stringify(dom), INJECTED)).toBe(0);
        expect(count(stringify(mapped), INJECTED)).toBe(3);

        const re = /name: 'article'/;
        expect(inspect(dom)).toNotMatch(re);
        expect(inspect(mapped)).toMatch(re);
      });

      it('should correctly append multiple nodes where an array is returned', function () {
        /**
         * Duplicate all list items that occur - assign them a class.
         *
         * @param {Object}
         *
         * @returns {Object|Array}
         */
        function fn(node) {
          if (adapter.isElementNode(node) && adapter.getTagName(node) === 'li') {
            const id = adapter.getAttrList(node)[0].value;
            const newNodes = [
              null, // Just to make sure it's filtered.
              node,
              adapter.createElement(
                'li',
                XHTML_NAMESPACE,
                [{ name: 'id', value: `inserted:${id}` }],
              ),
            ];

            return newNodes;
          }

          return node;
        }

        const dom = createIndexedModel();
        const mapper = map.bind(null, fn);

        const mapped = mapper(dom);

        expect(count(stringify(dom), LIST_ITEM)).toBe(3);
        expect(count(stringify(mapped), LIST_ITEM)).toBe(6);

        const ids = [];
        /**
         * Returns a clone, pushes ids into an array.
         *
         * @param {Object}
         *
         * @returns {Object}
         */
        function push(node) {
          if (adapter.isElementNode(node)) {
            ids.unshift(adapter.getAttrList(node)[0].value);
          }

          return node;
        }

        map.bind(null, push)(mapped);

        // Ensure the correct insertion order.
        expect(ids).toEqual([
          '0.1',
          '0.1.1',
          '0.1.1.1',
          'inserted:0.1.1.1',
          '0.1.1.2',
          'inserted:0.1.1.2',
          '0.1.1.3',
          'inserted:0.1.1.3',
          '0.1.2',
        ]);
      });
    });
  });

  describe('reduce', function () {
    it('is intended to be partially applied for composition', function () {
      const reducer = reduce.bind(null, noop);
      expect(reducer).toBeA('function');
    });

    // Second parameter is a `string`, `number` or `function`.
    it('should accept a second parameter as an initial value', function () {
      // TODO: Increase the scope of this test, it doesn't cover enough.
      ['', 1, function () { return {}; }].forEach(function (i) {
        const reducer = reduce.bind(null, noop, i);
        expect(reducer).toBeA('function');
      });
    });

    /**
     * NOTE: This particular test is a bit much, I'm really just
     * playing around with the adapter methods provided by parse5's
     * `htmlparser2` adapter.
     */
    describe('partially applied reduce', function () {
      // TODO: This function is completely broken... sort it.
      it('should traverse the dom in the correct order', function () {
        /**
         * As with `map`, we have two several tests. Firstly, we can
         * check both the type of each node as it comes through.
         */
        (function () {
          /**
           * Determine the node type, unshift into an array.
           *
           * @param {Mixed} previous value
           * @param {Object} node
           *
           * @returns {Mixed}
           */
          function fn(p, node) {
            // Root node.
            if (adapter.isRootNode(node)) {
              p = `root ${p}`;
            }

            // Element node.
            if (adapter.isElementNode(node)) {
              const tagName = adapter.getTagName(node);
              p = `${tagName} ${p}`;
            }

            // Text node.
            if (adapter.isTextNode(node)) {
              p = `text ${p}`;
            }

            // Comment node.
            if (adapter.isCommentNode(node)) {
              p = `comment ${p}`;
            }

            return p;
          }

          const reducer = reduce.bind(null, fn, '');
          const dom = createModel();

          expect(reducer(dom).trim()).toBe('root comment text div text');
        }());

        /**
         * A test for using a `Number` primative as the initial value,
         * this also checks against an indexed dom and ensure that
         * that the nodes are being passed in the correct order.
         */
        (function () {
          const ids = [];
          /**
           * increments as we come acrros element nodes.
           *
           * @param {Mixed} previous value
           * @param {Object} node
           *
           * @returns {Mixed}
           */
          function fn(p, node) {
            if (adapter.isElementNode(node)) {
              const id = adapter.getAttrList(node)[0].value;
              ids.unshift(id);
              p++;
            }

            return p;
          }

          const reducer = reduce.bind(null, fn, 0);
          const dom = createIndexedModel();

          const output = reducer(dom);
          expect(output).toBe(ids.length);
          expect(ids).toEqual([
            '0.1',
            '0.1.1',
            '0.1.1.1',
            '0.1.1.2',
            '0.1.1.3',
            '0.1.2',
          ]);
        }());
      });

      // TODO: Here the value 'init' is a function that just returns an array.
      it('if the initial value is a function, the return value should be passed', function () {
        /**
         * A function to be called to create the initial value.
         *
         * @return {Array}
         */
        const i = function () {
          return [];
        };

        /**
         * Unshifts tag names or types into the previous value.
         *
         * @param {Array} the previous value
         * @param {Object} the current node
         *
         * @returns {Array}
         */
        function fn(p, node) {
          const type = node.type;
          p.unshift(type === 'tag' ? node.name : type);
          return p;
        }

        const reducer = reduce.bind(null, fn, i);
        const dom = createIndexedModel();

        expect(reducer(dom)).toEqual([
          'root',
          'div',
          'ul',
          'li',
          'li',
          'li',
          'p',
        ]);
      });
    });
  });
});


text:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

// The Scoreboard class manages showing the score to the player
public class Scoreboard : MonoBehaviour {
	public static Scoreboard S; // The singleton for Scoreboard

	public GameObject    prefabFloatingScore;

	public bool ________________;
	[SerializeField]
	private int          _score = 0;
	public string        _scoreString;

	// The score property also sets the scoreString
	public int score {
		get {
			return(_score);
		}
		set {
			_score = value;
			scoreString = Utils.AddCommasToNumber(_score);
		}
	}

	// The scoreString property also sets the GUIText.text
	public string scoreString {
		get {
			return(_scoreString);
		}
		set {
			_scoreString = value;
			GetComponent<GUIText>().text = _scoreString;
		}
	}

	void Awake() {
		S = this;
	}

	// When called by SendMessage, this adds the fs.score to this.score
	public void FSCallback(FloatingScore fs) {
		score += fs.score;
	}

	// This will Instantiate a new FloatingScore GameObject and initialize it.
	// It also returns a pointer to the FloatingScore created so that the
	//  calling function can do more with it (like set fontSizes, etc.)
	public FloatingScore CreateFloatingScore(int amt, List<Vector3> pts) {
		GameObject go = Instantiate(prefabFloatingScore) as GameObject;
		FloatingScore fs = go.GetComponent<FloatingScore>();
		fs.score = amt;
		fs.reportFinishTo = this; // Set fs to call back to this
		fs.Init(pts);
		return(fs);
	}

}

redpajama_set_name: RedPajamaGithub


text:
package com.realism.common.block;

import com.realism.common.block.tileentity.TileEntityTestBlock;

import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;

public class TestBlock extends BlockContainer {

	public TestBlock(Material materialIn) {
		super(materialIn);
		this.setCreativeTab(CreativeTabs.tabBlock);
		this.setHardness(1f);
		this.setResistance(2f);
	}

	public int getRenderType() {
		return -1;
	}

	public boolean isOpaqueCube() {
		return false;
	}

	public boolean renderAsNormalBlock() {
		return false;
	}

	@Override
	public TileEntity createNewTileEntity(World worldIn, int meta) {
		return new TileEntityTestBlock();
	}

}


text:
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { BulletComponent } from './bullet.component';

describe('BulletComponent', () => {
  let component: BulletComponent;
  let fixture: ComponentFixture<BulletComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ BulletComponent ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(BulletComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});


text:
module Graphics (initGL, draw) where

import FRP.Yampa.Vector3
import Unsafe.Coerce

import Graphics.UI.GLUT hiding (Level,Vector3(..),normalize)
import qualified Graphics.UI.GLUT as G(Vector3(..))

import Types

initGL :: IO ()
initGL = do
    getArgsAndInitialize
    initialDisplayMode $= [WithDepthBuffer, DoubleBuffered]
    createWindow       "Bouncy Ball!"
    depthFunc          $= Just Less
    clearColor         $= Color4 0 0 0 0
    light (Light 0)    $= Enabled
    lighting           $= Enabled
    lightModelAmbient  $= Color4 0.5 0.5 0.5 1
    diffuse (Light 0)  $= Color4 1 1 1 1
    blend              $= Enabled
    blendFunc          $= (SrcAlpha, OneMinusSrcAlpha)
    colorMaterial      $= Just (FrontAndBack, AmbientAndDiffuse)
    reshapeCallback    $= Just resizeScene
    return ()

resizeScene :: Size -> IO ()
resizeScene (Size w 0) = resizeScene (Size w 1) -- prevent divide by zero
resizeScene s@(Size width height) = do
    viewport   $= (Position 0 0, s)
    matrixMode $= Projection
    loadIdentity
    perspective 45 (w2/h2) 1 1000
    matrixMode $= Modelview 0
    where
        w2 = half width
        h2 = half height
        half z = realToFrac z / 2

draw :: Pos -> IO ()
draw pos = do
    clear [ColorBuffer, DepthBuffer]
    loadIdentity
    -- TODO: How do you actually do this? As in: safely?
    renderPlayer $ vector3 2 (unsafeCoerce pos) (-30)
    swapBuffers
    where
        size = 6
        size2 :: R
        size2 = (fromInteger $ size) / 2
        red = Color4 1.0 0.7 0.8 1.0 :: Color4 R
        renderShapeAt s p = preservingMatrix $ do
            translate $ G.Vector3 (0.5 - size2 + vector3X p)
                                  (0.5 - size2 + vector3Y p)
                                  (0.5 - size2 + vector3Z p)
            renderObject Solid s
        renderPlayer   = (color red >>) . (renderShapeAt $ Sphere' 0.5 20 20)


text:
@interface BookChapter : _BookChapter

- (void)deleteWithSuccess:(void (^)())success failure:(void (^)(NSError *))failure;

@end


text:
package go_kafka_client

import (
	"encoding/json"
	"errors"
	"fmt"
	"path"
	"sort"
	"strconv"
	"strings"
	"time"

	"github.com/samuel/go-zookeeper/zk"
)

var (
	consumersPath    = "/consumers"
	brokerIdsPath    = "/brokers/ids"
	brokerTopicsPath = "/brokers/topics"
)

type GroupWatch struct {
	coordinatorEvents chan CoordinatorEvent
	zkEvents          chan zk.Event
	poisonPillMessage string
}

// ZookeeperCoordinator implements ConsumerCoordinator and OffsetStorage interfaces and is used to coordinate multiple consumers that work within the same consumer group
// as well as storing and retrieving their offsets.
type ZookeeperCoordinator struct {
	config      *ZookeeperConfig
	zkConn      *zk.Conn
	unsubscribe chan bool
	closed      bool
	watches     map[string]*GroupWatch
}

func (this *ZookeeperCoordinator) String() string {
	return "zk"
}

// Creates a new ZookeeperCoordinator with a given configuration.
// The new created ZookeeperCoordinator does NOT automatically connect to zookeeper, you should call Connect() explicitly
func NewZookeeperCoordinator(Config *ZookeeperConfig) *ZookeeperCoordinator {
	return &ZookeeperCoordinator{
		config:      Config,
		unsubscribe: make(chan bool),
		watches:     make(map[string]*GroupWatch),
	}
}

/* Establish connection to this ConsumerCoordinator. Returns an error if fails to connect, nil otherwise. */
func (this *ZookeeperCoordinator) Connect() (err error) {
	var connectionEvents <-chan zk.Event
	for i := 0; i <= this.config.MaxRequestRetries; i++ {
		this.zkConn, connectionEvents, err = this.tryConnect()
		if err == nil {
			go this.listenConnectionEvents(connectionEvents)
			return
		}
		Tracef(this, "Zookeeper connect failed after %d-th retry", i)
		time.Sleep(this.config.RequestBackoff)
	}

	return
}

func (this *ZookeeperCoordinator) tryConnect() (zkConn *zk.Conn, connectionEvents <-chan zk.Event, err error) {
	Infof(this, "Connecting to ZK at %s\n", this.config.ZookeeperConnect)
	zkConn, connectionEvents, err = zk.Connect(this.config.ZookeeperConnect, this.config.ZookeeperSessionTimeout)
	return
}

func (this *ZookeeperCoordinator) Disconnect() {
	Infof(this, "Closing connection to ZK at %s\n", this.config.ZookeeperConnect)
	this.closed = true
	this.zkConn.Close()
}

func (this *ZookeeperCoordinator) listenConnectionEvents(connectionEvents <-chan zk.Event) {
	for event := range connectionEvents { // will be closed by zk.Conn when it's stopped
		Infof(this, "Received zkConnectionEvent Type: %s Server: %s State: %s", event.Type.String(), event.Server, event.State.String())
		switch event.State {
		case zk.StateConnecting:
			// (Re)connecting to a ZK server
			// Nothing to do
		case zk.StateConnected:
			// (Re)connected to a ZK server (TCP layer)
			// We have no idea about ZK session at this moment
			// Nothing to do
		case zk.StateExpired:
			// Failed to reuse the previous session (timeout)
			// Existing watchers will be discarded
			// Exsiting ephemeral nodes will be removed
			for _, watch := range this.watches {
				watch.coordinatorEvents <- Reinitialize
			}

		case zk.StateHasSession:
			// Got an new or existing session
			// Nothing to do
		}
	}
	Infof(this, "Stopping listening connection events")
}

/* Registers a new consumer with Consumerid id and TopicCount subscription that is a part of consumer group Groupid in this ConsumerCoordinator. Returns an error if registration failed, nil otherwise. */
func (this *ZookeeperCoordinator) RegisterConsumer(Consumerid string, Groupid string, TopicCount TopicsToNumStreams) (err error) {
	backoffMultiplier := 1
	this.ensureZkPathsExist(Groupid)
	for i := 0; i <= this.config.MaxRequestRetries; i++ {
		err = this.tryRegisterConsumer(Consumerid, Groupid, TopicCount)
		if err == nil {
			return
		}
		Tracef(this, "Registering consumer %s in group %s failed after %d-th retry", Consumerid, Groupid, i)
		time.Sleep(this.config.RequestBackoff * time.Duration(backoffMultiplier))
		backoffMultiplier++
	}
	return
}

func (this *ZookeeperCoordinator) tryRegisterConsumer(Consumerid string, Groupid string, TopicCount TopicsToNumStreams) (err error) {
	Debugf(this, "Trying to register consumer %s at group %s in Zookeeper", Consumerid, Groupid)
	registryDir := newZKGroupDirs(this.config.Root, Groupid).ConsumerRegistryDir
	pathToConsumer := fmt.Sprintf("%s/%s", registryDir, Consumerid)
	data, mappingError := json.Marshal(&ConsumerInfo{
		Version:      int16(1),
		Subscription: TopicCount.GetTopicsToNumStreamsMap(),
		Pattern:      TopicCount.Pattern(),
		Timestamp:    time.Now().Unix() * 1000,
	})
	if mappingError != nil {
		return mappingError
	}

	Debugf(this, "Path: %s", pathToConsumer)

	_, err = this.zkConn.Create(pathToConsumer, data, zk.FlagEphemeral, zk.WorldACL(zk.PermAll))
	if err == zk.ErrNoNode {
		err = this.createOrUpdatePathParentMayNotExistFailFast(registryDir, make([]byte, 0))
		if err != nil {
			return
		}
		_, err = this.zkConn.Create(pathToConsumer, data, zk.FlagEphemeral, zk.WorldACL(zk.PermAll))
	} else if err == zk.ErrNodeExists {
		var stat *zk.Stat
		_, stat, err = this.zkConn.Get(pathToConsumer)
		if err != nil {
			Debugf(this, "%v; path: %s", err, pathToConsumer)
			return err
		}
		_, err = this.zkConn.Set(pathToConsumer, data, stat.Version)
		if err != nil {
			Debugf(this, "%v; path: %s", err, pathToConsumer)
			return err
		}
	}

	return
}

/* Deregisters consumer with Consumerid id that is a part of consumer group Groupid form this ConsumerCoordinator. Returns an error if deregistration failed, nil otherwise. */
func (this *ZookeeperCoordinator) DeregisterConsumer(Consumerid string, Groupid string) (err error) {
	path := fmt.Sprintf("%s/%s", newZKGroupDirs(this.config.Root, Groupid).ConsumerRegistryDir, Consumerid)
	Debugf(this, "Trying to deregister consumer at path: %s", path)
	backoffMultiplier := 1
	for i := 0; i <= this.config.MaxRequestRetries; i++ {
		err = this.deleteNode(path)
		if err == nil {
			return
		}
		Tracef(this, "Deregistering consumer %s in group %s failed after %d-th retry", Consumerid, Groupid, i)
		time.Sleep(this.config.RequestBackoff * time.Duration(backoffMultiplier))
		backoffMultiplier++
	}
	return
}

// Gets the information about consumer with Consumerid id that is a part of consumer group Groupid from this ConsumerCoordinator.
// Returns ConsumerInfo on success and error otherwise (For example if consumer with given Consumerid does not exist).
func (this *ZookeeperCoordinator) GetConsumerInfo(Consumerid string, Groupid string) (info *ConsumerInfo, err error) {
	backoffMultiplier := 1
	for i := 0; i <= this.config.MaxRequestRetries; i++ {
		info, err = this.tryGetConsumerInfo(Consumerid, Groupid)
		if err == nil {
			return
		}
		Tracef(this, "GetConsumerInfo failed for consumer %s in group %s after %d-th retry", Consumerid, Groupid, i)
		time.Sleep(this.config.RequestBackoff * time.Duration(backoffMultiplier))
		backoffMultiplier++
	}
	return
}

func (this *ZookeeperCoordinator) tryGetConsumerInfo(Consumerid string, Groupid string) (*ConsumerInfo, error) {
	zkPath := fmt.Sprintf("%s/%s", newZKGroupDirs(this.config.Root, Groupid).ConsumerRegistryDir, Consumerid)
	data, _, err := this.zkConn.Get(zkPath)
	if err != nil {
		Debugf(this, "%v; path: %s", err, zkPath)
		return nil, err
	}

	type consumerInfoTmp struct {
		Version      int16
		Subscription map[string]int
		Pattern      string
		Timestamp    json.RawMessage
	}
	tmpInfo := &consumerInfoTmp{}
	err = json.Unmarshal(data, tmpInfo)

	if err != nil {
		return nil, fmt.Errorf("%v Path: %s, Data: %s", err, zkPath, string(data))
	}

	ts, convErr := fixTimestamp(tmpInfo.Timestamp)
	if convErr != nil {
		return nil, fmt.Errorf("%v Path: %s, Data: %s", err, zkPath, string(data))
	}
	consumerInfo := &ConsumerInfo{Version: tmpInfo.Version, Subscription: tmpInfo.Subscription, Pattern: tmpInfo.Pattern, Timestamp: ts}
	return consumerInfo, nil
}

func fixTimestamp(b json.RawMessage) (int64, error) {
	var s string
	var i int64
	var err error
	err = json.Unmarshal(b, &s)
	if err == nil {
		var n int64
		n, err = strconv.ParseInt(s, 10, 64)
		if err == nil {
			return n, nil
		}
	}
	err = json.Unmarshal(b, &i)
	if err == nil {
		return i, nil
	}
	return 0, fmt.Errorf("Unable to convert raw value %+v to int64", b)
}

// Gets the information about consumers per topic in consumer group Groupid excluding internal topics (such as offsets) if ExcludeInternalTopics = true.
// Returns a map where keys are topic names and values are slices of consumer ids and fetcher ids associated with this topic and error on failure.
func (this *ZookeeperCoordinator) GetConsumersPerTopic(Groupid string, ExcludeInternalTopics bool) (consumers map[string][]ConsumerThreadId, err error) {
	backoffMultiplier := 1
	for i := 0; i <= this.config.MaxRequestRetries; i++ {
		consumers, err = this.tryGetConsumersPerTopic(Groupid, ExcludeInternalTopics)
		if err == nil {
			return
		}
		Tracef(this, "GetConsumersPerTopic failed for group %s after %d-th retry", Groupid, i)
		time.Sleep(this.config.RequestBackoff * time.Duration(backoffMultiplier))
		backoffMultiplier++
	}
	return
}

func (this *ZookeeperCoordinator) tryGetConsumersPerTopic(Groupid string, ExcludeInternalTopics bool) (map[string][]ConsumerThreadId, error) {
	consumers, err := this.GetConsumersInGroup(Groupid)
	if err != nil {
		return nil, err
	}
	consumersPerTopicMap := make(map[string][]ConsumerThreadId)
	for _, consumer := range consumers {
		topicsToNumStreams, err := NewTopicsToNumStreams(Groupid, consumer, this, ExcludeInternalTopics)
		if err != nil {
			return nil, err
		}

		for topic, threadIds := range topicsToNumStreams.GetConsumerThreadIdsPerTopic() {
			for _, threadId := range threadIds {
				consumersPerTopicMap[topic] = append(consumersPerTopicMap[topic], threadId)
			}
		}
	}

	for topic := range consumersPerTopicMap {
		sort.Sort(byName(consumersPerTopicMap[topic]))
	}

	return consumersPerTopicMap, nil
}

/* Gets the list of all consumer ids within a consumer group Groupid. Returns a slice containing all consumer ids in group and error on failure. */
func (this *ZookeeperCoordinator) GetConsumersInGroup(Groupid string) (consumers []string, err error) {
	backoffMultiplier := 1
	for i := 0; i <= this.config.MaxRequestRetries; i++ {
		consumers, err = this.tryGetConsumersInGroup(Groupid)
		if err == nil {
			return
		}
		Tracef(this, "GetConsumersInGroup failed for group %s after %d-th retry", Groupid, i)
		time.Sleep(this.config.RequestBackoff * time.Duration(backoffMultiplier))
		backoffMultiplier++
	}
	return
}

func (this *ZookeeperCoordinator) tryGetConsumersInGroup(Groupid string) (consumers []string, err error) {
	Debugf(this, "Getting consumers in group %s", Groupid)
	zkPath := newZKGroupDirs(this.config.Root, Groupid).ConsumerRegistryDir
	consumers, _, err = this.zkConn.Children(zkPath)
	if err != nil {
		Debugf(this, "%v; path: %s", err, zkPath)
		return nil, err
	}
	return
}

/* Gets the list of all topics registered in this ConsumerCoordinator. Returns a slice conaining topic names and error on failure. */
func (this *ZookeeperCoordinator) GetAllTopics() (topics []string, err error) {
	backoffMultiplier := 1
	for i := 0; i <= this.config.MaxRequestRetries; i++ {
		topics, err = this.tryGetAllTopics()
		if err == nil {
			return
		}
		Tracef(this, "GetAllTopics failed after %d-th retry", i)
		time.Sleep(this.config.RequestBackoff * time.Duration(backoffMultiplier))
		backoffMultiplier++
	}
	return
}

func (this *ZookeeperCoordinator) rootedPath(path string) string {
	return this.config.Root + path
}

func (this *ZookeeperCoordinator) tryGetAllTopics() (topics []string, err error) {
	zkPath := this.rootedPath(brokerTopicsPath)
	topics, _, err = this.zkConn.Children(zkPath)
	if err != nil {
		Debugf(this, "%v; path: %s", err, zkPath)
		return nil, err
	}
	return
}

// Gets the information about existing partitions for a given Topics.
// Returns a map where keys are topic names and values are slices of partition ids associated with this topic and error on failure.
func (this *ZookeeperCoordinator) GetPartitionsForTopics(Topics []string) (partitions map[string][]int32, err error) {
	backoffMultiplier := 1
	for i := 0; i <= this.config.MaxRequestRetries; i++ {
		partitions, err = this.tryGetPartitionsForTopics(Topics)
		if err == nil {
			return
		}
		Tracef(this, "GetPartitionsForTopics for topics %s failed after %d-th retry", Topics, i)
		time.Sleep(this.config.RequestBackoff * time.Duration(backoffMultiplier))
		backoffMultiplier++
	}
	return
}

func (this *ZookeeperCoordinator) tryGetPartitionsForTopics(Topics []string) (map[string][]int32, error) {
	result := make(map[string][]int32)
	partitionAssignments, err := this.getPartitionAssignmentsForTopics(Topics)
	if err != nil {
		return nil, err
	}
	for topic, partitionAssignment := range partitionAssignments {
		for partition, _ := range partitionAssignment {
			result[topic] = append(result[topic], partition)
		}
	}

	for topic, _ := range partitionAssignments {
		sort.Sort(intArray(result[topic]))
	}

	return result, nil
}

// Gets the information about all Kafka brokers registered in this ConsumerCoordinator.
// Returns a slice of BrokerInfo and error on failure.
func (this *ZookeeperCoordinator) GetAllBrokers() (brokers []*BrokerInfo, err error) {
	backoffMultiplier := 1
	for i := 0; i <= this.config.MaxRequestRetries; i++ {
		brokers, err = this.tryGetAllBrokers()
		if err == nil {
			return
		}
		Tracef(this, "GetAllBrokers failed after %d-th retry", i)
		time.Sleep(this.config.RequestBackoff * time.Duration(backoffMultiplier))
		backoffMultiplier++
	}
	return
}

func (this *ZookeeperCoordinator) tryGetAllBrokers() ([]*BrokerInfo, error) {
	Debug(this, "Getting all brokers in cluster")
	zkPath := this.rootedPath(brokerIdsPath)
	brokerIds, _, err := this.zkConn.Children(zkPath)
	if err != nil {
		Debugf(this, "%v; path: %s", err, zkPath)
		return nil, err
	}
	brokers := make([]*BrokerInfo, len(brokerIds))
	for i, brokerId := range brokerIds {
		brokerIdNum, err := strconv.Atoi(brokerId)
		if err != nil {
			return nil, err
		}

		brokers[i], err = this.getBrokerInfo(int32(brokerIdNum))
		if err != nil {
			return nil, err
		}
		brokers[i].Id = int32(brokerIdNum)
	}

	return brokers, nil
}

// Gets the offset for a given topic, partition and consumer group.
// Returns offset on sucess, error otherwise.
func (this *ZookeeperCoordinator) GetOffset(Groupid string, topic string, partition int32) (offset int64, err error) {
	backoffMultiplier := 1
	for i := 0; i <= this.config.MaxRequestRetries; i++ {
		offset, err = this.tryGetOffsetForTopicPartition(Groupid, topic, partition)
		if err == nil {
			return
		}
		Tracef(this, "GetOffset for group %s, topic %s and partition %d failed after %d-th retry", Groupid, topic, partition, i)
		time.Sleep(this.config.RequestBackoff * time.Duration(backoffMultiplier))
		backoffMultiplier++
	}
	return
}

func (this *ZookeeperCoordinator) tryGetOffsetForTopicPartition(Groupid string, topic string, partition int32) (int64, error) {
	dirs := newZKGroupTopicDirs(this.config.Root, Groupid, topic)
	zkPath := fmt.Sprintf("%s/%d", dirs.ConsumerOffsetDir, partition)
	offset, _, err := this.zkConn.Get(zkPath)
	if err != nil {
		if err == zk.ErrNoNode {
			return InvalidOffset, nil
		} else {
			Debugf(this, "%v; path: %s", err, zkPath)
			return InvalidOffset, err
		}
	}

	offsetNum, err := strconv.Atoi(string(offset))
	if err != nil {
		return InvalidOffset, err
	}

	return int64(offsetNum), nil
}

// Subscribes for any change that should trigger consumer rebalance on consumer group Groupid in this ConsumerCoordinator.
// Returns a read-only channel of booleans that will get values on any significant coordinator event (e.g. new consumer appeared, new broker appeared etc.) and error if failed to subscribe.
func (this *ZookeeperCoordinator) SubscribeForChanges(Groupid string) (events <-chan CoordinatorEvent, err error) {
	backoffMultiplier := 1
	for i := 0; i <= this.config.MaxRequestRetries; i++ {
		events, err = this.trySubscribeForChanges(Groupid)
		if err == nil {
			return
		}
		Tracef(this, "SubscribeForChanges for group %s failed after %d-th retry", Groupid, i)
		time.Sleep(this.config.RequestBackoff * time.Duration(backoffMultiplier))
		backoffMultiplier++
	}
	return
}

func (this *ZookeeperCoordinator) trySubscribeForChanges(Groupid string) (<-chan CoordinatorEvent, error) {
	var groupWatch *GroupWatch
	if _, ok := this.watches[Groupid]; !ok {
		groupWatch = &GroupWatch{
			coordinatorEvents: make(chan CoordinatorEvent, 100),
			poisonPillMessage: uuid(),
		}
		this.watches[Groupid] = groupWatch
	} else {
		groupWatch = this.watches[Groupid]
	}

	Infof(this, "Subscribing for changes for %s", Groupid)
	zkEvents := make(chan zk.Event, 100)
	this.watches[Groupid].zkEvents = zkEvents

	consumersWatcher, err := this.getConsumersInGroupWatcher(Groupid)
	if err != nil {
		return nil, err
	}
	blueGreenWatcher, err := this.getBlueGreenWatcher(Groupid)
	if err != nil {
		return nil, err
	}
	topicsWatcher, err := this.getTopicsWatcher()
	if err != nil {
		return nil, err
	}
	brokersWatcher, err := this.getAllBrokersInClusterWatcher()
	if err != nil {
		return nil, err
	}

	inputChannels := make([]*<-chan zk.Event, 0)
	inputChannels = append(inputChannels, &consumersWatcher, &blueGreenWatcher, &topicsWatcher, &brokersWatcher)
	stopRedirecting := redirectChannelsTo(inputChannels, zkEvents)

	go func() {
		for {
			select {
			case e := <-zkEvents:
				{
					Infof(this, "Received zkEvent Type: %s State: %s Path: %s", e.Type.String(), e.State.String(), e.Path)
					if e.Type != zk.EventNotWatching && e.State != zk.StateDisconnected {
						if strings.HasPrefix(e.Path, fmt.Sprintf("%s/%s",
							newZKGroupDirs(this.config.Root, Groupid).ConsumerApiDir, BlueGreenDeploymentAPI)) {
							groupWatch.coordinatorEvents <- BlueGreenRequest
						} else {
							groupWatch.coordinatorEvents <- Regular
						}
					}

					if strings.HasPrefix(e.Path, newZKGroupDirs(this.config.Root, Groupid).ConsumerRegistryDir) {
						Info(this, "Trying to renew watcher for consumer registry")
						consumersWatcher, err = this.getConsumersInGroupWatcher(Groupid)
						if err != nil {
							this.config.PanicHandler(err)
						}
					} else if strings.HasPrefix(e.Path, fmt.Sprintf("%s/%s", newZKGroupDirs(this.config.Root, Groupid).ConsumerApiDir, BlueGreenDeploymentAPI)) {
						Info(this, "Trying to renew watcher for consumer API dir")
						blueGreenWatcher, err = this.getBlueGreenWatcher(Groupid)
						if err != nil {
							this.config.PanicHandler(err)
						}
					} else if strings.HasPrefix(e.Path, this.rootedPath(brokerTopicsPath)) {
						Info(this, "Trying to renew watcher for consumer topic dir")
						topicsWatcher, err = this.getTopicsWatcher()
						if err != nil {
							this.config.PanicHandler(err)
						}
					} else if strings.HasPrefix(e.Path, this.rootedPath(brokerIdsPath)) {
						Info(this, "Trying to renew watcher for brokers in cluster")
						brokersWatcher, err = this.getAllBrokersInClusterWatcher()
						if err != nil {
							this.config.PanicHandler(err)
						}
					} else {
						Warnf(this, "Unknown event path: %s", e.Path)
					}

					stopRedirecting <- true
					stopRedirecting = redirectChannelsTo(inputChannels, zkEvents)
				}
			case <-this.unsubscribe:
				{
					stopRedirecting <- true
					return
				}
			}
		}
	}()

	return groupWatch.coordinatorEvents, nil
}

// Gets all deployed topics for consume group Group from consumer coordinator.
// Returns a map where keys are notification ids and values are DeployedTopics. May also return an error (e.g. if failed to reach coordinator).
func (this *ZookeeperCoordinator) GetBlueGreenRequest(Group string) (topics map[string]*BlueGreenDeployment, err error) {
	backoffMultiplier := 1
	for i := 0; i <= this.config.MaxRequestRetries; i++ {
		topics, err = this.tryGetBlueGreenRequest(Group)
		if err == nil {
			return
		}
		Tracef(this, "GetNewDeployedTopics for group %s failed after %d-th retry", Group, i)
		time.Sleep(this.config.RequestBackoff * time.Duration(backoffMultiplier))
		backoffMultiplier++
	}
	return
}

func (this *ZookeeperCoordinator) tryGetBlueGreenRequest(Group string) (map[string]*BlueGreenDeployment, error) {
	apiPath := fmt.Sprintf("%s/%s", newZKGroupDirs(this.config.Root, Group).ConsumerApiDir, BlueGreenDeploymentAPI)
	children, _, err := this.zkConn.Children(apiPath)
	if err != nil {
		return nil, errors.New(fmt.Sprintf("Unable to get new deployed topics %s: %s", err.Error(), apiPath))
	}

	deployedTopics := make(map[string]*BlueGreenDeployment)
	for _, child := range children {
		entryPath := fmt.Sprintf("%s/%s", apiPath, child)
		rawDeployedTopicsEntry, _, err := this.zkConn.Get(entryPath)
		if err != nil {
			return nil, errors.New(fmt.Sprintf("Unable to fetch deployed topic entry %s: %s", err.Error(), entryPath))
		}
		deployedTopicsEntry := &BlueGreenDeployment{}
		err = json.Unmarshal(rawDeployedTopicsEntry, deployedTopicsEntry)
		if err != nil {
			return nil, errors.New(fmt.Sprintf("Unable to parse deployed topic entry %s: %s", err.Error(), rawDeployedTopicsEntry))
		}

		deployedTopics[child] = deployedTopicsEntry
	}

	return deployedTopics, nil
}

func (this *ZookeeperCoordinator) RequestBlueGreenDeployment(blue BlueGreenDeployment, green BlueGreenDeployment) error {
	var err error
	backoffMultiplier := 1
	for i := 0; i <= this.config.MaxRequestRetries; i++ {
		err := this.tryRequestBlueGreenDeployment(green.Group, blue)
		if err == nil {
			break
		}
		Tracef(this, "DeployTopics for group %s and topics %s failed after %d-th retry", green.Group, blue.Topics, i)
		time.Sleep(this.config.RequestBackoff * time.Duration(backoffMultiplier))
		backoffMultiplier++
	}

	if err != nil {
		return err
	}

	backoffMultiplier = 1
	for i := 0; i <= this.config.MaxRequestRetries; i++ {
		err := this.tryRequestBlueGreenDeployment(blue.Group, green)
		if err == nil {
			return err
		}
		Tracef(this, "DeployTopics for group %s and topics %s failed after %d-th retry", blue.Group, green.Topics, i)
		time.Sleep(this.config.RequestBackoff * time.Duration(backoffMultiplier))
		backoffMultiplier++
	}

	return err
}

func (this *ZookeeperCoordinator) tryRequestBlueGreenDeployment(Group string, blueOrGreen BlueGreenDeployment) error {
	data, err := json.Marshal(blueOrGreen)
	if err != nil {
		return err
	}
	return this.createOrUpdatePathParentMayNotExistFailFast(fmt.Sprintf("%s/%s/%d", newZKGroupDirs(this.config.Root, Group).ConsumerApiDir, BlueGreenDeploymentAPI, time.Now().Unix()), data)
}

func (this *ZookeeperCoordinator) RemoveOldApiRequests(group string) (err error) {
	for _, api := range availableAPIs {
		err = this.tryRemoveOldApiRequests(group, api)
		if err != nil {
			break
		}
	}
	return
}

func (this *ZookeeperCoordinator) tryRemoveOldApiRequests(group string, api ConsumerGroupApi) error {
	requests := make([]string, 0)
	var err error

	apiPath := fmt.Sprintf("%s/%s", newZKGroupDirs(this.config.Root, group).ConsumerApiDir, api)
	for i := 0; i <= this.config.MaxRequestRetries; i++ {
		requests, _, err = this.zkConn.Children(apiPath)
		if err != nil {
			continue
		}
		for _, request := range requests {
			var data []byte
			var t int64
			childPath := fmt.Sprintf("%s/%s", apiPath, request)
			if api == Rebalance {
				if data, _, err = this.zkConn.Get(childPath); err != nil && err == zk.ErrNoNode {
					// It's possible another consumer deleted the node before we could read it's data
					continue
				}
				if t, err = strconv.ParseInt(string(data), 10, 64); err != nil {
					t = int64(0) // If the data isn't a timestamp ensure it will be deleted anyway.
				}
			} else if api == BlueGreenDeploymentAPI {
				if t, err = strconv.ParseInt(string(request), 10, 64); err != nil {
					break
				}
			}

			// Delete if this zk node has an expired timestamp
			if time.Unix(t, 0).Before(time.Now().Add(-10 * time.Minute)) {
				// If the data is not a timestamp or is a timestamp but has reached expiration delete it
				err = this.deleteNode(childPath)
				if err != nil && err != zk.ErrNoNode {
					break
				}
			}
		}
	}

	return err
}

func (this *ZookeeperCoordinator) AwaitOnStateBarrier(consumerId string, group string, barrierName string,
	barrierSize int, api string, timeout time.Duration) bool {
	barrierPath := fmt.Sprintf("%s/%s/%s", newZKGroupDirs(this.config.Root, group).ConsumerApiDir, api, barrierName)

	var barrierExpiration time.Time
	var err error
	// Block and wait for this to consumerId to join the state barrier
	if barrierExpiration, err = this.joinStateBarrier(barrierPath, consumerId, timeout); err == nil {
		// Now that we've joined the barrier wait to verify all consumers have reached consensus.
		barrierTimeout := barrierExpiration.Sub(time.Now())
		err = this.waitForMembersToJoin(barrierPath, barrierSize, barrierTimeout)
	}

	if err != nil {
		// Encountered an error waiting for consensus... Fail it
		Errorf(this, "Failed awaiting on state barrier %s [%v]", barrierName, err)
		return false
	}

	Infof(this, "Successfully awaited on state barrier %s", barrierName)
	return true
}

func (this *ZookeeperCoordinator) joinStateBarrier(barrierPath, consumerId string, timeout time.Duration) (time.Time, error) {
	deadline := time.Now().Add(timeout)
	var err error
	Infof(this, "Joining state barrier %s", barrierPath)
	for i := 0; i <= this.config.MaxRequestRetries; i++ {
		// Attempt to create the barrier path, with a shared deadline
		_, err = this.zkConn.Create(barrierPath, []byte(strconv.FormatInt(deadline.Unix(), 10)), 0, zk.WorldACL(zk.PermAll))
		if err != nil {
			if err != zk.ErrNodeExists {
				continue
			}
			// If the barrier path already exists, read it's value
			if data, _, err := this.zkConn.Get(barrierPath); err == nil {
				deadlineInt, _ := strconv.ParseInt(string(data), 10, 64)
				deadline = time.Unix(deadlineInt, 0)
				Infof(this, "Barrier already exists with deadline set to %v. Joining...", deadline)
			} else {
				continue
			}
		}
		// Register our consumerId as a child node on the barrierPath. This should notify other consumers we have joined.
		// Need to join as an ephemeral node to ensure that if the barrier Id is re-used we aren't permanently registered giving false counts.
		if _, err = this.zkConn.Create(fmt.Sprintf("%s/%s", barrierPath, consumerId), make([]byte, 0), zk.FlagEphemeral, zk.WorldACL(zk.PermAll)); err == nil || err == zk.ErrNodeExists {
			Infof(this, "Successfully joined state barrier %s", barrierPath)
			return deadline, nil
		}
		Warnf(this, "Failed to join state barrier %s, retrying...", barrierPath)
	}
	return time.Now(), fmt.Errorf("Failed to join state barrier %s after %d retries [%v]", barrierPath, this.config.MaxRequestRetries, err)
}

func (this *ZookeeperCoordinator) waitForMembersToJoin(barrierPath string, expected int, timeout time.Duration) error {
	// Will be used to make sure we don't leave the zk watcher channel without someone to receive events off it.
	blackholeFunc := func(blackhole <-chan zk.Event) {
		<-blackhole
	}

	t := time.NewTimer(timeout)
	defer t.Stop()
	for {
		select {
		// Using a priority select to provide precedence to the timeout
		case <-t.C:
			return fmt.Errorf("Timed out waiting for consensus on barrier path %s", barrierPath)
		default:
			children, _, zkMemberJoinedWatcher, err := this.zkConn.ChildrenW(barrierPath)
			if err != nil && err == zk.ErrNoNode {
				return fmt.Errorf("%v; path: %s", err, barrierPath)
			} else if len(children) == expected {
				// don't leave the zkMemberJoinedWatcher chan out there with no one to receive the message it produces later as it would cause a block.
				go blackholeFunc(zkMemberJoinedWatcher)
				return nil
			}
			// Haven't seen all expected consumers on this barrier path.  Watch for changes to the path...
			select {
			case <-t.C:
				go blackholeFunc(zkMemberJoinedWatcher)
				return fmt.Errorf("Timed out waiting for consensus on barrier path %s", barrierPath)
			case <-zkMemberJoinedWatcher:
				continue
			}
		}
	}

	return nil
}

func (this *ZookeeperCoordinator) RemoveStateBarrier(group string, stateHash string, api string) error {
	var err error
	backoffMultiplier := 1
	for i := 0; i <= this.config.MaxRequestRetries; i++ {
		err = this.tryRemoveStateBarrier(group, stateHash, api)
		if err == nil || err == zk.ErrNoNode {
			return nil
		}
		Tracef(this, "State assertion deletion %s in group %s failed after %d-th retry", hash, group, i)
		time.Sleep(this.config.RequestBackoff * time.Duration(backoffMultiplier))
		backoffMultiplier++
	}

	return err
}

func (this *ZookeeperCoordinator) tryRemoveStateBarrier(group string, stateHash string, api string) error {
	path := fmt.Sprintf("%s/%s/%s", newZKGroupDirs(this.config.Root, group).ConsumerApiDir, api, stateHash)
	Debugf(this, "Trying to fail rebalance at path: %s", path)

	return this.deleteNode(path)
}

func (this *ZookeeperCoordinator) deleteNode(path string) error {
	children, _, err := this.zkConn.Children(path)
	if err != nil {
		Debugf(this, "%v; path: %s", err, path)
		return err
	}
	for _, child := range children {
		err := this.deleteNode(fmt.Sprintf("%s/%s", path, child))
		if err != nil && err != zk.ErrNoNode {
			return err
		}
	}

	_, stat, err := this.zkConn.Get(path)
	if err != nil {
		Debugf(this, "%v; path: %s", err, path)
		return err
	}
	return this.zkConn.Delete(path, stat.Version)
}

/* Tells the ConsumerCoordinator to unsubscribe from events for the consumer it is associated with. */
func (this *ZookeeperCoordinator) Unsubscribe() {
	this.unsubscribe <- true
}

// Tells the ConsumerCoordinator to claim partition topic Topic and partition Partition for consumerThreadId fetcher that works within a consumer group Group.
// Returns true if claim is successful, false and error explaining failure otherwise.
func (this *ZookeeperCoordinator) ClaimPartitionOwnership(Groupid string, Topic string, Partition int32, consumerThreadId ConsumerThreadId) (bool, error) {
	var err error
	backoffMultiplier := 1
	for i := 0; i <= this.config.MaxRequestRetries; i++ {
		ok, err := this.tryClaimPartitionOwnership(Groupid, Topic, Partition, consumerThreadId)
		if ok {
			return ok, err
		}
		Tracef(this, "Claim failed for topic %s, partition %d after %d-th retry", Topic, Partition, i)
		time.Sleep(this.config.RequestBackoff * time.Duration(backoffMultiplier))
		backoffMultiplier++
	}
	return false, err
}

func (this *ZookeeperCoordinator) tryClaimPartitionOwnership(group string, topic string, partition int32, consumerThreadId ConsumerThreadId) (bool, error) {
	dirs := newZKGroupTopicDirs(this.config.Root, group, topic)
	this.createOrUpdatePathParentMayNotExistFailFast(dirs.ConsumerOwnerDir, make([]byte, 0))

	pathToOwn := fmt.Sprintf("%s/%d", dirs.ConsumerOwnerDir, partition)
	_, err := this.zkConn.Create(pathToOwn, []byte(consumerThreadId.String()), zk.FlagEphemeral, zk.WorldACL(zk.PermAll))
	if err == zk.ErrNoNode {
		err = this.createOrUpdatePathParentMayNotExistFailFast(dirs.ConsumerOwnerDir, make([]byte, 0))
		if err != nil {
			return false, err
		}
		_, err = this.zkConn.Create(pathToOwn, []byte(consumerThreadId.String()), zk.FlagEphemeral, zk.WorldACL(zk.PermAll))
	}

	if err != nil {
		if err == zk.ErrNodeExists {
			var data []byte
			if data, _, err = this.zkConn.Get(pathToOwn); err == nil && string(data) == consumerThreadId.String() {
				// If the current owner of the partition is the same consumer Id as the current one, carry on.
				return true, nil
			}
			Debugf(consumerThreadId, "waiting for the partition ownership to be deleted: %d", partition)
			return false, nil
		} else {
			Error(consumerThreadId, err)
			return false, err
		}
	}

	Debugf(this, "Successfully claimed partition %d in topic %s for %s", partition, topic, consumerThreadId)

	return true, nil
}

// Tells the ConsumerCoordinator to release partition ownership on topic Topic and partition Partition for consumer group Groupid.
// Returns error if failed to released partition ownership.
func (this *ZookeeperCoordinator) ReleasePartitionOwnership(Groupid string, Topic string, Partition int32) error {
	var err error
	backoffMultiplier := 1
	for i := 0; i <= this.config.MaxRequestRetries; i++ {
		err = this.tryReleasePartitionOwnership(Groupid, Topic, Partition)
		if err == nil {
			return err
		}
		Tracef(this, "ReleasePartitionOwnership failed for group %s, topic %s, partition %d after %d-th retry", Groupid, Topic, Partition, i)
		time.Sleep(this.config.RequestBackoff * time.Duration(backoffMultiplier))
		backoffMultiplier++
	}
	return err
}

func (this *ZookeeperCoordinator) tryReleasePartitionOwnership(group string, topic string, partition int32) error {
	path := fmt.Sprintf("%s/%d", newZKGroupTopicDirs(this.config.Root, group, topic).ConsumerOwnerDir, partition)
	err := this.deleteNode(path)
	if err != nil && err != zk.ErrNoNode {
		return err
	} else {
		return nil
	}
}

// Tells the ConsumerCoordinator to commit offset Offset for topic and partition TopicPartition for consumer group Groupid.
// Returns error if failed to commit offset.
func (this *ZookeeperCoordinator) CommitOffset(Groupid string, Topic string, Partition int32, Offset int64) error {
	dirs := newZKGroupTopicDirs(this.config.Root, Groupid, Topic)
	err := this.updateRecord(fmt.Sprintf("%s/%d", dirs.ConsumerOffsetDir, Partition), []byte(strconv.FormatInt(Offset, 10)))
	if err == zk.ErrNoNode {
		return this.createOrUpdatePathParentMayNotExistFailFast(fmt.Sprintf("%s/%d", dirs.ConsumerOffsetDir, Partition), []byte(strconv.FormatInt(Offset, 10)))
	}

	return err
}

func (this *ZookeeperCoordinator) ensureZkPathsExist(group string) {
	dirs := newZKGroupDirs(this.config.Root, group)
	this.createOrUpdatePathParentMayNotExistFailSafe(dirs.ConsumerDir, make([]byte, 0))
	this.createOrUpdatePathParentMayNotExistFailSafe(dirs.ConsumerGroupDir, make([]byte, 0))
	this.createOrUpdatePathParentMayNotExistFailSafe(dirs.ConsumerRegistryDir, make([]byte, 0))
	this.createOrUpdatePathParentMayNotExistFailSafe(dirs.ConsumerApiDir, make([]byte, 0))
	for _, api := range availableAPIs {
		this.createOrUpdatePathParentMayNotExistFailSafe(fmt.Sprintf("%s/%s", dirs.ConsumerApiDir, api), make([]byte, 0))
	}
}

func (this *ZookeeperCoordinator) getWatcher(path string) (<-chan zk.Event, error) {
	Debugf(this, "Getting watcher for %s", path)

	var watcher <-chan zk.Event
	var err error
	backoffMultiplier := 1
	for i := 0; i <= this.config.MaxRequestRetries; i++ {
		_, _, watcher, err = this.zkConn.ChildrenW(path)
		if err == nil {
			return watcher, err
		}
		Debugf(this, "%v; path: %s", err, path)
		time.Sleep(this.config.RequestBackoff * time.Duration(backoffMultiplier))
		backoffMultiplier++
	}

	return nil, err
}

func (this *ZookeeperCoordinator) getAllBrokersInClusterWatcher() (<-chan zk.Event, error) {
	return this.getWatcher(this.rootedPath(brokerIdsPath))
}

func (this *ZookeeperCoordinator) getConsumersInGroupWatcher(group string) (<-chan zk.Event, error) {
	return this.getWatcher(newZKGroupDirs(this.config.Root, group).ConsumerRegistryDir)
}

func (this *ZookeeperCoordinator) getBlueGreenWatcher(group string) (<-chan zk.Event, error) {
	return this.getWatcher(fmt.Sprintf("%s/%s", newZKGroupDirs(this.config.Root, group).ConsumerApiDir, BlueGreenDeploymentAPI))
}

func (this *ZookeeperCoordinator) getTopicsWatcher() (<-chan zk.Event, error) {
	return this.getWatcher(this.rootedPath(brokerTopicsPath))
}

func (this *ZookeeperCoordinator) getBrokerInfo(brokerId int32) (*BrokerInfo, error) {
	Debugf(this, "Getting info for broker %d", brokerId)
	pathToBroker := fmt.Sprintf("%s/%d", this.rootedPath(brokerIdsPath), brokerId)
	data, _, zkError := this.zkConn.Get(pathToBroker)
	if zkError != nil {
		Debugf(this, "%v; path: %s", zkError, pathToBroker)
		return nil, zkError
	}

	broker := &BrokerInfo{}
	mappingError := json.Unmarshal([]byte(data), broker)

	return broker, mappingError
}

func (this *ZookeeperCoordinator) getPartitionAssignmentsForTopics(topics []string) (map[string]map[int32][]int32, error) {
	Debugf(this, "Trying to get partition assignments for topics %v", topics)
	result := make(map[string]map[int32][]int32)
	for _, topic := range topics {
		topicInfo, err := this.getTopicInfo(topic)
		if err != nil {
			return nil, err
		}
		result[topic] = make(map[int32][]int32)
		for partition, replicaIds := range topicInfo.Partitions {
			partitionInt, err := strconv.Atoi(partition)
			if err != nil {
				return nil, err
			}
			result[topic][int32(partitionInt)] = replicaIds
		}
	}

	return result, nil
}

func (this *ZookeeperCoordinator) getTopicInfo(topic string) (*TopicInfo, error) {
	zkPath := fmt.Sprintf("%s/%s", this.rootedPath(brokerTopicsPath), topic)
	data, _, err := this.zkConn.Get(zkPath)
	if err != nil {
		Debugf(this, "%v; path: %s", err, zkPath)
		return nil, err
	}
	topicInfo := &TopicInfo{}
	err = json.Unmarshal(data, topicInfo)
	if err != nil {
		return nil, err
	}

	return topicInfo, nil
}

func (this *ZookeeperCoordinator) createOrUpdatePathParentMayNotExistFailSafe(pathToCreate string, data []byte) error {
	return this.createOrUpdatePathParentMayNotExist(pathToCreate, data, true)
}

func (this *ZookeeperCoordinator) createOrUpdatePathParentMayNotExistFailFast(pathToCreate string, data []byte) error {
	return this.createOrUpdatePathParentMayNotExist(pathToCreate, data, false)
}

func (this *ZookeeperCoordinator) createOrUpdatePathParentMayNotExist(pathToCreate string, data []byte, failSafe bool) error {
	Debugf(this, "Trying to create path %s in Zookeeper", pathToCreate)
	_, err := this.zkConn.Create(pathToCreate, data, 0, zk.WorldACL(zk.PermAll))
	if err != nil {
		if zk.ErrNodeExists == err {
			if len(data) > 0 {
				Debugf(this, "Trying to update existing node %s", pathToCreate)
				return this.updateRecord(pathToCreate, data)
			} else {
				return nil
			}
		} else {
			parent, _ := path.Split(pathToCreate)
			if len(parent) == 0 {
				return errors.New("Specified blank path")
			}
			err = this.createOrUpdatePathParentMayNotExist(parent[:len(parent)-1], make([]byte, 0), failSafe)
			if err != nil {
				if zk.ErrNodeExists != err {
					Error(this, err.Error())
				}
				return err
			} else {
				Debugf(this, "Successfully created path %s", parent[:len(parent)-1])
			}

			Debugf(this, "Trying again to create path %s in Zookeeper", pathToCreate)
			_, err = this.zkConn.Create(pathToCreate, data, 0, zk.WorldACL(zk.PermAll))
			if err == zk.ErrNodeExists && failSafe {
				err = nil
			}
		}
	}

	return err
}

func (this *ZookeeperCoordinator) updateRecord(pathToCreate string, dataToWrite []byte) error {
	Debugf(this, "Trying to update path %s", pathToCreate)
	_, stat, _ := this.zkConn.Get(pathToCreate)
	_, err := this.zkConn.Set(pathToCreate, dataToWrite, stat.Version)
	if err != nil {
		return err
	}
	return nil
}

/* ZookeeperConfig is used to pass multiple configuration entries to ZookeeperCoordinator. */
type ZookeeperConfig struct {
	/* Zookeeper hosts */
	ZookeeperConnect []string

	/* Zookeeper session timeout */
	ZookeeperSessionTimeout time.Duration

	/* Max retries for any request except CommitOffset. CommitOffset is controlled by ConsumerConfig.OffsetsCommitMaxRetries. */
	MaxRequestRetries int

	/* Backoff to retry any request */
	RequestBackoff time.Duration

	/* kafka Root */
	Root string

	// PanicHandler is a function that will be called when unrecoverable error occurs to give the possibility to perform cleanups, recover from panic etc
	PanicHandler func(error)
}

/* Created a new ZookeeperConfig with sane defaults. Default ZookeeperConnect points to localhost. */
func NewZookeeperConfig() *ZookeeperConfig {
	config := &ZookeeperConfig{}
	config.ZookeeperConnect = []string{"localhost"}
	config.ZookeeperSessionTimeout = 5 * time.Second
	config.MaxRequestRetries = 3
	config.RequestBackoff = 150 * time.Millisecond
	config.Root = ""
	config.PanicHandler = func(e error) {
		panic(e)
	}

	return config
}

// ZookeeperConfigFromFile is a helper function that loads zookeeper configuration information from file.
// The file accepts the following fields:
//  zookeeper.connect
//  zookeeper.kafka.root
//  zookeeper.connection.timeout
//  zookeeper.max.request.retries
//  zookeeper.request.backoff
// The configuration file entries should be constructed in key=value syntax. A # symbol at the beginning
// of a line indicates a comment. Blank lines are ignored. The file should end with a newline character.
func ZookeeperConfigFromFile(filename string) (*ZookeeperConfig, error) {
	z, err := LoadConfiguration(filename)
	if err != nil {
		return nil, err
	}

	config := NewZookeeperConfig()
	setStringSliceConfig(&config.ZookeeperConnect, z["zookeeper.connect"], ",")
	setStringConfig(&config.Root, z["zookeeper.kafka.root"])

	if err := setDurationConfig(&config.ZookeeperSessionTimeout, z["zookeeper.connection.session.timeout"]); err != nil {
		return nil, err
	}
	if err := setIntConfig(&config.MaxRequestRetries, z["zookeeper.max.request.retries"]); err != nil {
		return nil, err
	}
	if err := setDurationConfig(&config.RequestBackoff, z["zookeeper.request.backoff"]); err != nil {
		return nil, err
	}

	return config, nil
}

type zkGroupDirs struct {
	Group                string
	ConsumerDir          string
	ConsumerGroupDir     string
	ConsumerRegistryDir  string
	ConsumerApiDir       string
	ConsumerRebalanceDir string
}

func newZKGroupDirs(root string, group string) *zkGroupDirs {
	consumerPathRooted := fmt.Sprintf("%s%s", root, consumersPath)
	consumerGroupDir := fmt.Sprintf("%s/%s", consumerPathRooted, group)
	consumerRegistryDir := fmt.Sprintf("%s/ids", consumerGroupDir)
	consumerApiDir := fmt.Sprintf("%s/api", consumerGroupDir)
	consumerRebalanceDir := fmt.Sprintf("%s/api/rebalance", consumerGroupDir)
	return &zkGroupDirs{
		Group:                group,
		ConsumerDir:          consumerPathRooted,
		ConsumerGroupDir:     consumerGroupDir,
		ConsumerRegistryDir:  consumerRegistryDir,
		ConsumerApiDir:       consumerApiDir,
		ConsumerRebalanceDir: consumerRebalanceDir,
	}
}

type zkGroupTopicDirs struct {
	ZkGroupDirs       *zkGroupDirs
	Topic             string
	ConsumerOffsetDir string
	ConsumerOwnerDir  string
}

func newZKGroupTopicDirs(root string, group string, topic string) *zkGroupTopicDirs {
	zkGroupsDirs := newZKGroupDirs(root, group)
	return &zkGroupTopicDirs{
		ZkGroupDirs:       zkGroupsDirs,
		Topic:             topic,
		ConsumerOffsetDir: fmt.Sprintf("%s/%s/%s", zkGroupsDirs.ConsumerGroupDir, "offsets", topic),
		ConsumerOwnerDir:  fmt.Sprintf("%s/%s/%s", zkGroupsDirs.ConsumerGroupDir, "owners", topic),
	}
}

//used for tests only
type mockZookeeperCoordinator struct {
	commitHistory map[TopicAndPartition]int64
}

func newMockZookeeperCoordinator() *mockZookeeperCoordinator {
	return &mockZookeeperCoordinator{
		commitHistory: make(map[TopicAndPartition]int64),
	}
}

func (mzk *mockZookeeperCoordinator) Connect() error { panic("Not implemented") }
func (mzk *mockZookeeperCoordinator) Disconnect()    { panic("Not implemented") }
func (mzk *mockZookeeperCoordinator) RegisterConsumer(consumerid string, group string, topicCount TopicsToNumStreams) error {
	panic("Not implemented")
}
func (mzk *mockZookeeperCoordinator) DeregisterConsumer(consumerid string, group string) error {
	panic("Not implemented")
}
func (mzk *mockZookeeperCoordinator) GetConsumerInfo(consumerid string, group string) (*ConsumerInfo, error) {
	panic("Not implemented")
}
func (mzk *mockZookeeperCoordinator) GetConsumersPerTopic(group string, excludeInternalTopics bool) (map[string][]ConsumerThreadId, error) {
	panic("Not implemented")
}
func (mzk *mockZookeeperCoordinator) GetConsumersInGroup(group string) ([]string, error) {
	panic("Not implemented")
}
func (mzk *mockZookeeperCoordinator) GetAllTopics() ([]string, error) { panic("Not implemented") }
func (mzk *mockZookeeperCoordinator) GetPartitionsForTopics(topics []string) (map[string][]int32, error) {
	panic("Not implemented")
}
func (mzk *mockZookeeperCoordinator) GetAllBrokers() ([]*BrokerInfo, error) { panic("Not implemented") }
func (mzk *mockZookeeperCoordinator) GetOffset(group string, topic string, partition int32) (int64, error) {
	panic("Not implemented")
}
func (mzk *mockZookeeperCoordinator) SubscribeForChanges(group string) (<-chan CoordinatorEvent, error) {
	panic("Not implemented")
}
func (mzk *mockZookeeperCoordinator) RequestBlueGreenDeployment(blue BlueGreenDeployment, green BlueGreenDeployment) error {
	panic("Not implemented")
}
func (mzk *mockZookeeperCoordinator) GetBlueGreenRequest(Group string) (map[string]*BlueGreenDeployment, error) {
	panic("Not implemented")
}
func (mzk *mockZookeeperCoordinator) AwaitOnStateBarrier(consumerId string, group string, stateHash string, barrierSize int, api string, timeout time.Duration) bool {
	panic("Not implemented")
}
func (mzk *mockZookeeperCoordinator) Unsubscribe() { panic("Not implemented") }
func (mzk *mockZookeeperCoordinator) ClaimPartitionOwnership(group string, topic string, partition int32, consumerThreadId ConsumerThreadId) (bool, error) {
	panic("Not implemented")
}
func (mzk *mockZookeeperCoordinator) ReleasePartitionOwnership(group string, topic string, partition int32) error {
	panic("Not implemented")
}
func (mzk *mockZookeeperCoordinator) CommitOffset(group string, topic string, partition int32, offset int64) error {
	mzk.commitHistory[TopicAndPartition{topic, partition}] = offset
	return nil
}
func (this *mockZookeeperCoordinator) RemoveOldApiRequests(group string) error {
	panic("Not implemented")
}

func (this *mockZookeeperCoordinator) RemoveStateBarrier(group string, stateHash string, api string) error {
	panic("Not implemented")
}


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <title>cmppolicylabel module — Nitro  documentation</title>

    <link rel="stylesheet" href="_static/default.css" type="text/css" />
    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />

    <link rel="top" title="Nitro  documentation" href="index.html" />
    <link rel="up" title="cmp package" href="nssrc.com.citrix.netscaler.nitro.resource.config.cmp.html" />
    <link rel="next" title="cmppolicylabel_binding module" href="nssrc.com.citrix.netscaler.nitro.resource.config.cmp.cmppolicylabel_binding.html" />
    <link rel="prev" title="cmppolicy_lbvserver_binding module" href="nssrc.com.citrix.netscaler.nitro.resource.config.cmp.cmppolicy_lbvserver_binding.html" />

Navigation

          index

          next |

          previous |

Nitro  documentation »

config package »

cmp package »

cmppolicylabel module¶

class <tt class="descname">cmppolicylabel</tt>¶

Bases: <tt class="xref py py-class docutils literal">nssrc.com.citrix.netscaler.nitro.resource.base.base_resource.base_resource</tt>

Configuration for compression policy label resource.

<tt class="descname">labelname</tt>¶

Name of the HTTP compression policy label. Must begin with a letter, number, or the underscore character (_). Additional characters allowed, after the first character, are the hyphen (-), period (.) pound sign (#), space ( ), at sign (@), equals (=), and colon (:). The name must be unique within the list of policy labels for compression policies. Can be renamed after the policy label is created.
The following requirement applies only to the NetScaler CLI:
If the name includes one or more spaces, enclose the name in double or single quotation marks (for example, “my cmp policylabel” or ‘my cmp policylabel’).<br/>Minimum length =  1.

<tt class="descname">type</tt>¶

Type of packets (request packets or response) against which to match the policies bound to this policy label.<br/>Possible values = REQ, RES.

<tt class="descname">newname</tt>¶

New name for the compression policy label. Must begin with an ASCII alphabetic or underscore (_) character, and must contain only ASCII alphanumeric, underscore, hash (#), period (.), space, colon (:), at (@), equals (=), and hyphen (-) characters.
The following requirement applies only to the NetScaler CLI:
If the name includes one or more spaces, enclose the name in double or single quotation marks (for example, “my cmp policylabel” or ‘my cmp policylabel’).<br/>Minimum length =  1.

<tt class="descname">numpol</tt>¶

Number of polices bound to label.

<tt class="descname">hits</tt>¶

Number of times policy label was invoked.

<tt class="descname">priority</tt>¶

Specifies the priority of the policy.

<tt class="descname">gotopriorityexpression</tt>¶

Expression specifying the priority of the next policy which will get evaluated if the current policy rule evaluates to TRUE.

<tt class="descname">labeltype</tt>¶

Type of policy label invocation.<br/>Possible values = reqvserver, resvserver, policylabel.

<tt class="descname">invoke_labelname</tt>¶

Name of the label to invoke if the current policy evaluates to TRUE.

<tt class="descname">flowtype</tt>¶

Flowtype of the bound compression policy.

<tt class="descname">description</tt>¶

Description of the policylabel.

classmethod <tt class="descname">add</tt><big>(</big>client, resource<big>)</big>¶

Use this API to add cmppolicylabel.

classmethod <tt class="descname">delete</tt><big>(</big>client, resource<big>)</big>¶

Use this API to delete cmppolicylabel.

classmethod <tt class="descname">rename</tt><big>(</big>client, resource, new_labelname<big>)</big>¶

Use this API to rename a cmppolicylabel resource.

classmethod <tt class="descname">get</tt><big>(</big>client, name='', option_=''<big>)</big>¶

Use this API to fetch all the cmppolicylabel resources that are configured on netscaler.

classmethod <tt class="descname">get_filtered</tt><big>(</big>client, filter_<big>)</big>¶

Use this API to fetch filtered set of cmppolicylabel resources.
filter string should be in JSON format.eg: “port:80,servicetype:HTTP”.

classmethod <tt class="descname">count</tt><big>(</big>client<big>)</big>¶

Use this API to count the cmppolicylabel resources configured on NetScaler.

classmethod <tt class="descname">count_filtered</tt><big>(</big>client, filter_<big>)</big>¶

Use this API to count filtered the set of cmppolicylabel resources.
Filter string should be in JSON format.eg: “port:80,servicetype:HTTP”.

class <tt class="descname">Type</tt>¶

<tt class="descname">REQ</tt> = 'REQ'¶

<tt class="descname">RES</tt> = 'RES'¶

class <tt class="descclassname">cmppolicylabel.</tt><tt class="descname">Labeltype</tt>¶

<tt class="descname">reqvserver</tt> = 'reqvserver'¶

<tt class="descname">resvserver</tt> = 'resvserver'¶

<tt class="descname">policylabel</tt> = 'policylabel'¶

class <tt class="descname">cmppolicylabel_response</tt><big>(</big>length=1<big>)</big>¶

Bases: <tt class="xref py py-class docutils literal">nssrc.com.citrix.netscaler.nitro.resource.base.base_response.base_response</tt>

Nitro exception Package

Base Package

Service Package

Util Package

Config Package

aaa

app

appflow

appfw

appqoe

audit

authentication

authorization

autoscale

basic

ca

cache

cluster

cmp

cmpaction

cmpglobal_binding

cmpglobal_cmppolicy_binding

cmpparameter

cmppolicy

cmppolicy_binding

cmppolicy_cmpglobal_binding

cmppolicy_cmppolicylabel_binding

cmppolicy_crvserver_binding

cmppolicy_csvserver_binding

cmppolicy_lbvserver_binding

cmppolicylabel

cmppolicylabel_binding

cmppolicylabel_cmppolicy_binding

cmppolicylabel_policybinding_binding

cr

cs

db

dns

dos

feo

filter

gslb

ha

ipsec

lb

lldp

network

ns

ntp

policy

pq

protocol

responder

rewrite

rise

router

sc

snmp

spillover

ssl

stream

system

tm

transform

tunnel

utility

vpn

wi

Stat Package

Previous topic

cmppolicy_lbvserver_binding module

Next topic

cmppolicylabel_binding module

This Page

Show Source

Quick search

    <form class="search" action="search.html" method="get">
      <input type="text" name="q" />
      <input type="submit" value="Go" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>

    Enter search terms or a module, class or function name.

        © Copyright © 1999-2014 Citrix Systems, Inc. All Rights Reserved.
      Created using Sphinx 1.2.


text:
/**
 *
 */
package org.olat.lms.notifications;

import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyListOf;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.mockito.ArgumentCaptor;
import org.olat.data.basesecurity.Identity;
import org.olat.data.notifications.NotificationsDao;
import org.olat.data.notifications.Publisher;
import org.olat.data.notifications.Subscriber;
import org.olat.data.properties.PropertyImpl;
import org.olat.data.properties.PropertyManager;
import org.olat.data.user.Preferences;
import org.olat.data.user.User;
import org.olat.data.user.UserConstants;
import org.olat.lms.commons.i18n.I18nManagerStaticDependenciesWrapper;
import org.olat.lms.commons.i18n.I18nModule;
import org.olat.lms.commons.i18n.TestI18nManagerInitializer;
import org.olat.presentation.framework.core.translator.PackageUtil;
import org.olat.presentation.framework.core.translator.Translator;
import org.olat.system.commons.StringHelper;
import org.olat.system.mail.MailTemplate;
import org.olat.system.mail.MailerResult;
import org.olat.system.security.OLATPrincipal;
import org.olat.system.security.PrincipalAttributes;

/**
 * @author patrick
 *
 */
public class ObjectMother {

	static final String THE_IDENTITY_LASTNAME = "Bichsel";
	static final String THE_IDENTITY_FIRSTNAME = "Peter";
	static final String THE_IDENTITY_NAME = "pbichsel";
	static final String ANY_IDENTITY_LASTNAME = "Birkenstock";
	static final String ANY_IDENTITY_FIRSTNAME = "Heidi";
	static final String ANY_IDENTITY_NAME = "hbirkenstock";
	private NotificationsDao notificationsDaoMock;
	private Publisher anyPublisher;
	private Publisher thePublisher;
	private NotificationsHandler notificationsHandler;
	private NotificationServiceStaticDependenciesWrapper staticDependencyMock;
	private SubscriptionContext subscriptionContext;
	private Subscriber anySubscriber;
	private Subscriber theSubscriber;
	private SubscriptionInfo theSubscriberSubscriptionInfo;
	private Identity theIdentity;
	private Preferences theIdentityPreferences;
	private ArrayList<Subscriber> subscribers;
	private HashMap<String, Object> notificationHandlersMap;
	final static Long RES_ID = Long.valueOf(123);
	final static String SUBIDENTIFIER = "SUBIDENTIFIER";
	final static String PUBLISHER_TYPE = "InfoMessage";
	final static String RES_NAME = "RES_NAME";;
	private final Locale objectMotherLocale;
	private final Date objectMotherLatestMailedDate;
	private TestI18nManagerInitializer testI18nManagerInitializer;
	private NotificationServiceImpl notificationService;
	private Identity anyIdentity;
	private Preferences anyIdentityPreferences;
	private PropertyManager propertyManagerMock;

	public ObjectMother(){
		this(Locale.ENGLISH, new Date(1970));
	}

	public ObjectMother(Locale locale, Date latestEmailDate) {
		objectMotherLocale = locale;
		objectMotherLatestMailedDate = latestEmailDate;

		testI18nManagerInitializer = org.olat.lms.commons.i18n.ObjectMother.setupI18nManagerForFallbackLocale(locale);

		//the following order of method calls is important
		initAnyPublisher();
		initThePublisher();
		initPeterBichselIdentity();
		initHeidiBirkenstockIdentity();
		initSimpleNotificationWorld(locale);
	}

	public ObjectMother createNotificationsWorld() {
		return this;
	}

	private void initSimpleNotificationWorld(Locale locale) {
		notificationsDaoMock = mock(NotificationsDao.class);
		when(notificationsDaoMock.isPublisherValid(anyPublisher)).thenReturn(true);

		staticDependencyMock = mock(NotificationServiceStaticDependenciesWrapper.class);
		when(staticDependencyMock.getLocaleFor(locale.getLanguage())).thenReturn(locale);

		propertyManagerMock = mock(PropertyManager.class);
		when(staticDependencyMock.getPropertyManager()).thenReturn(propertyManagerMock);

		subscriptionContext = new SubscriptionContext(RES_NAME, RES_ID, SUBIDENTIFIER);
		when(notificationsDaoMock.isPublisherValid(thePublisher)).thenReturn(true);

		anySubscriber = mock(Subscriber.class);
		when(anySubscriber.getPublisher()).thenReturn(anyPublisher);
		when(anySubscriber.getIdentity()).thenReturn(anyIdentity);

		theSubscriber = mock(Subscriber.class);
		when(theSubscriber.getPublisher()).thenReturn(thePublisher);
		when(theSubscriber.getIdentity()).thenReturn(theIdentity);

		theSubscriberSubscriptionInfo = mock(SubscriptionInfo.class);
		when(theSubscriberSubscriptionInfo.hasNews()).thenReturn(true);

		notificationsHandler = mock(NotificationsHandler.class);
		when(notificationsHandler.getType()).thenReturn(PUBLISHER_TYPE);
		when(notificationsHandler.createSubscriptionInfo(any(Subscriber.class), any(Locale.class), any(Date.class))).thenReturn(theSubscriberSubscriptionInfo);

		notificationHandlersMap = new HashMap<String, Object>();
		notificationHandlersMap.put(PUBLISHER_TYPE, notificationsHandler);
		when(staticDependencyMock.getNotificationHandlers()).thenReturn(notificationHandlersMap);

		subscribers = new ArrayList<Subscriber>();
		subscribers.add(theSubscriber);
		when(notificationsDaoMock.getSubscriberList(theIdentity, PUBLISHER_TYPE)).thenReturn(subscribers);

		notificationService = new NotificationServiceImpl(notificationsDaoMock,notificationHandlersMap, staticDependencyMock);

		Map<String, Boolean> intervals = new HashMap<String, Boolean>();
		intervals.put("weekly", Boolean.TRUE);
		intervals.put("daily", Boolean.TRUE);
		notificationService.setNotificationIntervals(intervals);
		notificationService.setDefaultNotificationInterval("daily");

	}

	private void initPeterBichselIdentity() {
		theIdentity = mock(Identity.class);
		User user = mock(User.class);
		when(user.getRawUserProperty(UserConstants.FIRSTNAME)).thenReturn(THE_IDENTITY_FIRSTNAME);
		when(user.getRawUserProperty(UserConstants.LASTNAME)).thenReturn(THE_IDENTITY_LASTNAME);

		theIdentityPreferences = mock(Preferences.class);
		when(theIdentity.getUser()).thenReturn(user);
		PrincipalAttributes principalAttributes = mock(PrincipalAttributes.class);
		when(principalAttributes.getFirstName()).thenReturn(THE_IDENTITY_FIRSTNAME);
		when(principalAttributes.getLastName()).thenReturn(THE_IDENTITY_LASTNAME);

		when(theIdentity.getAttributes()).thenReturn(principalAttributes);
		when(user.getPreferences()).thenReturn(theIdentityPreferences);
		when(theIdentityPreferences.getLanguage()).thenReturn(objectMotherLocale.getLanguage());

		when(theIdentity.getName()).thenReturn(THE_IDENTITY_NAME);
	}

	private void initHeidiBirkenstockIdentity() {
		anyIdentity = mock(Identity.class);
		User user = mock(User.class);
		when(user.getRawUserProperty(UserConstants.FIRSTNAME)).thenReturn(ANY_IDENTITY_FIRSTNAME);
		when(user.getRawUserProperty(UserConstants.LASTNAME)).thenReturn(ANY_IDENTITY_LASTNAME);

		anyIdentityPreferences = mock(Preferences.class);
		when(anyIdentity.getUser()).thenReturn(user);
		PrincipalAttributes principalAttributes = mock(PrincipalAttributes.class);
		when(principalAttributes.getFirstName()).thenReturn(ANY_IDENTITY_FIRSTNAME);
		when(principalAttributes.getLastName()).thenReturn(ANY_IDENTITY_LASTNAME);

		when(anyIdentity.getAttributes()).thenReturn(principalAttributes);
		when(user.getPreferences()).thenReturn(anyIdentityPreferences);
		when(anyIdentityPreferences.getLanguage()).thenReturn(objectMotherLocale.getLanguage());

		when(anyIdentity.getName()).thenReturn(ANY_IDENTITY_NAME);
	}

	private void initThePublisher() {
		thePublisher = mock(Publisher.class);
		when(thePublisher.getResName()).thenReturn(RES_NAME);
		when(thePublisher.getResId()).thenReturn(RES_ID);
		when(thePublisher.getSubidentifier()).thenReturn(SUBIDENTIFIER);
		when(thePublisher.getType()).thenReturn(PUBLISHER_TYPE);
	}

	private void initAnyPublisher() {
		anyPublisher = mock(Publisher.class);
		when(anyPublisher.getResName()).thenReturn("any_res");
		when(anyPublisher.getResId()).thenReturn(Long.valueOf(456));
		when(anyPublisher.getSubidentifier()).thenReturn("any_subidentifier");
		when(anyPublisher.getType()).thenReturn(PUBLISHER_TYPE);
	}

	public Map<String, Object> getNotificationHandlers() {
		return notificationHandlersMap;
	}

	public NotificationsDao getNotificationDao() {
		return notificationsDaoMock;
	}

	public NotificationServiceStaticDependenciesWrapper getNotificationStaticDependencyWrapper() {
		return staticDependencyMock;
	}

	public Publisher getAnyPublisher() {
		return anyPublisher;
	}

	public Publisher getThePublisher() {
		return thePublisher;
	}

	public SubscriptionContext getSubscriptionContext() {
		return subscriptionContext;
	}

	public Date getLatestEmailDate() {
		return objectMotherLatestMailedDate;
	}

	public Subscriber getAnySubscriber() {
		return anySubscriber;
	}

	public Subscriber getTheSubscriber() {
		return theSubscriber;
	}

	public SubscriptionInfo getSubscriptionInfo() {
		return theSubscriberSubscriptionInfo;
	}

	public Identity getTheIdendity() {
		return theIdentity;
	}

	public Identity getAnyIdentity() {
		return anyIdentity;
	}

	public List<Subscriber> getSubcribers() {
		return subscribers;
	}

	public Translator getTranslatorForNotifications() {
		return PackageUtil.createPackageTranslator(NotificationServiceImpl.CLASS_SERVING_FOR_PACKAGETRANSLATOR_CREATION, objectMotherLocale);
	}

	public NotificationServiceStaticDependenciesWrapper configureIdentityInNotificationDependencies(Identity identity){
		PrincipalAttributes attributes = identity.getAttributes();
		boolean isNotValidIdentityToMock = attributes == null;
		if(isNotValidIdentityToMock){
			throw new IllegalStateException("Provided Idenity has no PrincipalAttributes configured !");
		}
		String firstName = attributes.getFirstName();
		String lastName = attributes.getLastName();
		isNotValidIdentityToMock = !StringHelper.containsNonWhitespace(firstName) || !StringHelper.containsNonWhitespace(lastName);

		if(isNotValidIdentityToMock){
			throw new IllegalStateException("Provided Idenity has either Lastname or Firstname not configured (or both)!");
		}

		when(staticDependencyMock.getFormatedName(identity)).thenReturn(firstName+" "+lastName);
		when(staticDependencyMock.getMailFooter(identity, null)).thenReturn("*** Footer from Testing ***");

		return staticDependencyMock;
	}

	public void configureSendMailInNotificationDependencies(Identity recipient, int mailStatus) {
		MailerResult mailerResultMock = mock(MailerResult.class);
		checkForValidMailStatus(mailStatus);
		when(mailerResultMock.getReturnCode()).thenReturn(mailStatus);
		when(staticDependencyMock.sendMail(eq(recipient), anyListOf(OLATPrincipal.class), anyListOf(OLATPrincipal.class), any(MailTemplate.class), any(OLATPrincipal.class))).thenReturn(mailerResultMock );
	}

	private void checkForValidMailStatus(int mailStatus) {
		switch (mailStatus) {
		case MailerResult.ATTACHMENT_INVALID:
			break;
		case MailerResult.MAILHOST_UNDEFINED:
			break;
		case MailerResult.OK:
			break;
		case MailerResult.RECIPIENT_ADDRESS_ERROR:
			break;
		case MailerResult.SEND_GENERAL_ERROR:
			break;
		case MailerResult.SENDER_ADDRESS_ERROR:
			break;
		case MailerResult.TEMPLATE_GENERAL_ERROR:
			break;
		case MailerResult.TEMPLATE_PARSE_ERROR:
				break;
		default:
			throw new IllegalStateException("Your MailStatus is not valid, see MailerResult for valid stati");
		}

	}

	public NotificationServiceImpl getNotificationService() {
		return notificationService;
	}

	public List<Subscriber> configureValidSubscribers(Subscriber anySubscriber, Subscriber theSubscriber) {
		List<Subscriber> allValidSubscribes = new ArrayList<Subscriber>();
		allValidSubscribes.add(anySubscriber);
		allValidSubscribes.add(theSubscriber);
		when(notificationsDaoMock.getAllValidSubscribers()).thenReturn(allValidSubscribes);
		when(staticDependencyMock.getFormatedName(anyIdentity)).thenReturn(ObjectMother.ANY_IDENTITY_FIRSTNAME+" "+ObjectMother.ANY_IDENTITY_LASTNAME);
		when(staticDependencyMock.getFormatedName(theIdentity)).thenReturn(ObjectMother.THE_IDENTITY_FIRSTNAME+" "+ObjectMother.THE_IDENTITY_LASTNAME);
		return allValidSubscribes;
	}

	public PropertyImpl configureLatesEmailSentFor(Identity identity,Calendar lastRecordedMailDate) {
		//TODO:2011-10-13:PB: not nice to mock a value object! should be possible to instantiate
		PropertyImpl commonPropertyImplValue = mock(PropertyImpl.class);
		when(commonPropertyImplValue.getLongValue()).thenReturn(lastRecordedMailDate.getTimeInMillis());
		when(propertyManagerMock.findProperty(identity, null, null, null,
				NotificationServiceImpl.LATEST_EMAIL_USER_PROP)).thenReturn(commonPropertyImplValue);
		return commonPropertyImplValue;
	}

	public MailTemplate captureMailTemplateForVerification(int expectedTimes) {
		ArgumentCaptor<OLATPrincipal> senderCaptor = ArgumentCaptor.forClass(OLATPrincipal.class);
		ArgumentCaptor<OLATPrincipal> fromCaptor = ArgumentCaptor.forClass(OLATPrincipal.class);
		ArgumentCaptor<List<? extends OLATPrincipal>> recipientsCCCaptor = new ArgumentCaptor<List<? extends OLATPrincipal>>();
		ArgumentCaptor<List<? extends OLATPrincipal>> recipientsBCCCaptor = new ArgumentCaptor<List<? extends OLATPrincipal>>();
		ArgumentCaptor<MailTemplate> templateCaptor = ArgumentCaptor.forClass(MailTemplate.class);

		verify(staticDependencyMock, times(expectedTimes)).sendMail(
				fromCaptor.capture(),
				recipientsCCCaptor.capture(),
				recipientsBCCCaptor.capture(),
				templateCaptor.capture(),
				senderCaptor.capture());

		MailTemplate mailTemplate = templateCaptor.getValue();
		return mailTemplate;
	}

}


text:
<?php

namespace Beyerz\SimpleHMVCBundle\Command;

use Symfony\Component\HttpKernel\Bundle\BundleInterface;

/**
 * Extension of Sensio generator
 *
 * @author Lance Bailey <bailz777@gmail.com>
 */
abstract class GeneratorCommand extends \Sensio\Bundle\GeneratorBundle\Command\GeneratorCommand
{
    /**
     * @param BundleInterface|null $bundle
     * @return array
     */
    protected function getSkeletonDirs(BundleInterface $bundle = null)
    {
        $skeletonDirs = array();

        if (isset($bundle) && is_dir($dir = $bundle->getPath().'/Resources/SimpleHMVCBundle/skeleton')) {
            $skeletonDirs[] = $dir;
        }

        if (is_dir($dir = $this->getContainer()->get('kernel')->getRootdir().'/Resources/SimpleHMVCBundle/skeleton')) {
            $skeletonDirs[] = $dir;
        }

        $skeletonDirs[] = __DIR__.'/../Resources/skeleton';
        $skeletonDirs[] = __DIR__.'/../Resources';

        return $skeletonDirs;
    }
}


text:
<?php

namespace App\NotationBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Degree
 *
 * @ORM\Table(name="degree")
 * @ORM\Entity
 */
class Degree
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=30, nullable=false)
     */
    private $name;

    /**
     * @var integer
     *
     * @ORM\Column(name="level", type="integer", nullable=false)
     */
    private $level;

    /**
     * @var \Doctrine\Common\Collections\Collection
     *
     * @ORM\ManyToMany(targetEntity="Course", mappedBy="degree")
     */
    private $course;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->course = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Degree
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set level
     *
     * @param integer $level
     * @return Degree
     */
    public function setLevel($level)
    {
        $this->level = $level;

        return $this;
    }

    /**
     * Get level
     *
     * @return integer
     */
    public function getLevel()
    {
        return $this->level;
    }

    /**
     * Add course
     *
     * @param \App\NotationBundle\Entity\Course $course
     * @return Degree
     */
    public function addCourse(\App\NotationBundle\Entity\Course $course)
    {
        $this->course[] = $course;

        return $this;
    }

    /**
     * Remove course
     *
     * @param \App\NotationBundle\Entity\Course $course
     */
    public function removeCourse(\App\NotationBundle\Entity\Course $course)
    {
        $this->course->removeElement($course);
    }

    /**
     * Get course
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getCourse()
    {
        return $this->course;
    }
}


text:
"""
    Impact - Controller

    @author: Michael Howden (michael@sahanafoundation.org)
    @date-created: 2010-10-12
"""

prefix = request.controller
resourcename = request.function

if prefix not in deployment_settings.modules:
    raise HTTP(404, body="Module disabled: %s" % prefix)

# =============================================================================
def type():

    """ RESTful CRUD controller """

    return s3_rest_controller(prefix, resourcename)

# =============================================================================
def impact():

    """ RESTful CRUD controller """

    return s3_rest_controller(prefix, resourcename)

# END =========================================================================


text:
/// Copyright (c) 2012 Ecma International.  All rights reserved.
/**
 * @path ch15/15.4/15.4.4/15.4.4.21/15.4.4.21-3-7.js
 * @description Array.prototype.reduce - value of 'length' is a number (value is negative)
 */

function testcase() {

        function callbackfn(prevVal, curVal, idx, obj) {
            return (curVal === 11 && idx === 1);
        }

        var obj = { 1: 11, 2: 9, length: -4294967294 };

        return Array.prototype.reduce.call(obj, callbackfn, 1) === true;
    }
runTestCase(testcase);


text:
<configuration>

   <!-- Turn off third party chatter -->
	<logger name="org.apache" level="OFF"/>
	<logger name="httpclient.wire" level="OFF"/>

	<appender name="console.ref" class="ch.qos.logback.core.ConsoleAppender">
		<encoder>
			<pattern>%d{HH:mm:ss.SSS} [%thread] - %msg%n</pattern>
		</encoder>
	</appender>

	<appender name="lroad.logger.ref"
		class="ch.qos.logback.core.rolling.RollingFileAppender">
		<file>logs/lroad.log</file>
		<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
			<FileNamePattern>>logs/archive/lroad.%i.log</FileNamePattern>
			<MinIndex>1</MinIndex>
			<MaxIndex>10</MaxIndex>
		</rollingPolicy>
		<triggeringPolicy
			class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
			<MaxFileSize>50MB</MaxFileSize>
		</triggeringPolicy>
		<encoder>
			<pattern>%d{ISO8601} %-5level %C{1} [%M:%L] [%thread] - %msg%n
			</pattern>
		</encoder>
	</appender>

	<appender name="lroad.builder.ref" class="ch.qos.logback.classic.sift.SiftingAppender">
		<discriminator>
			<key>segId</key>
			<defaultValue>NA</defaultValue>
		</discriminator>
		<sift>
			<appender name="FILE-${segId}"
				class="ch.qos.logback.core.rolling.RollingFileAppender">
				<file>logs/${segId}.log</file>
				<rollingPolicy
					class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
					<FileNamePattern>logs/archive/${segId}.%i.log</FileNamePattern>
					<MinIndex>1</MinIndex>
					<MaxIndex>10</MaxIndex>
				</rollingPolicy>
				<triggeringPolicy
					class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
					<MaxFileSize>50MB</MaxFileSize>
				</triggeringPolicy>
				<encoder>
					<Pattern>%d{ISO8601} [%thread] - %msg%n</Pattern>
				</encoder>
			</appender>
		</sift>
	</appender>

	<root level="OFF">
		<appender-ref ref="console.ref"/>
	</root>

	<logger name="lroad.logger" level="DEBUG">
		<appender-ref ref="lroad.logger.ref"/>
	</logger>

	<logger name="lroad.builder" level="OFF" additivity="false">
		<appender-ref ref="lroad.builder.ref"/>
	</logger>

</configuration>


text:
Angular Lite - lightweight Angular implementation inspired by [Minko Gechev](http://blog.mgechev.com/2015/03/09/build-learn-your-own-light-lightweight-angularjs)

## Features:
 - [x] Scope
   - [ ] Isolated scope
   - [x] [Scope life-cycle](https://docs.angularjs.org/guide/scope)
   - [x] Watch collection
 - [x] Templates
   - [ ] Support for expressions {{}}
 - [ ] Filters
   - [ ]
 - [x] Directives
   - [x] Property binding using *ng-prop.inner-text*
   - [x] Attribute binding using *ng-attr.aria-role*
   - [x] Templates
   - [ ] Transclusion [How transclusion works in Angular](http://teropa.info/blog/2015/06/09/transclusion.html), [Transclusion](https://docs.angularjs.org/api/ng/service/$compile#transclusion)
   - [ ] "require" property to inject some parent directive/components
   - [ ] "ng-if" directive
   - [ ] "ng-repeat" directive. [How ng-repeat works](https://code.angularjs.org/1.4.9/docs/guide/compiler)
   - [ ]
 - [ ] Components as custom elements
   - [ ]
 - [x] Controller directive
   - [x] "controller as" feature
   - [ ]
 - [x] Dependency injection
   - [ ] Results caching
   - [ ] Support for providers in DI. Provider - is a way to customize resolving of some dependencies(for example $element, or parent components etc.)
   - [ ]
 - [ ] Add some examples
 - [ ]

## Lessons learned:
 - [Indirect call of constructor function with array of parameters](http://stackoverflow.com/a/8843181)
 -

## Resources used:
 - [How data binding work](http://stackoverflow.com/questions/9682092/how-does-data-binding-work-in-angularjs/9693933#9693933)
 - [Angular scope](https://docs.angularjs.org/guide/scope)
 - [Digest cycle in SPA](http://blog.bguiz.com/post/60397801810/digest-cycles-in-single-page-apps/)
 - Angular internals
   - [Angular internals in depth](https://www.smashingmagazine.com/2015/01/angularjs-internals-in-depth/)
   - [Angular internals in depth 2](https://www.smashingmagazine.com/2015/11/angularjs-internals-in-depth-part-2/)
   - [Angular internals slides](http://cvuorinen.github.io/angularjs-internals-slides/#/)
   - [Make your own angular - scopes and digest](http://teropa.info/blog/2013/11/03/make-your-own-angular-part-1-scopes-and-digest.html)
   - [How transclusion works](http://teropa.info/blog/2015/06/09/transclusion.html)
 - [NodeList and Array](https://toddmotto.com/a-comprehensive-dive-into-nodelists-arrays-converting-nodelists-and-understanding-the-dom/)
 - [For-in loop](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in)
 - Angular2 and Aurelia
   - [Porting an Angular 2.0 App to Aurelia](http://eisenbergeffect.bluespire.com/porting-an-angular-2-0-app-to-aurelia/)

Scope:
http://stackoverflow.com/questions/27485848/why-cant-multiple-directives-ask-for-an-isolated-scope-on-the-same-element