text:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
   >
    <RelativeLayout
        android:id="@+id/per_one"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="#5CACEE">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            >

            <ImageView
                android:id="@+id/per_back"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:layout_marginLeft="20dp"
                android:src="@mipmap/backhome"
                />
            <TextView
                android:id="@+id/per_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:textSize="18dp"
                android:text="个人中心"/>

            <ImageView
                android:id="@+id/per_index"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:layout_alignTop="@+id/reg_back"
                android:layout_alignParentRight="true"
                android:layout_marginRight="20dp"
                android:src="@mipmap/back"
                />

        </RelativeLayout>

    </RelativeLayout>

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/per_one"
        >

        <RelativeLayout
            android:id="@+id/per_two"
            android:layout_width="match_parent"
            android:layout_height="match_parent"

            >

            <RelativeLayout
                android:id="@+id/per_image"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@mipmap/bg"

                >

                <RelativeLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerInParent="true">

                    <com.zhimei.customview.CircleImageView
                        android:id="@+id/per_iv_image"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:src="@mipmap/test"
                        android:layout_centerHorizontal="true"
                        />

                    <TextView
                        android:id="@+id/per_tv_name"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:textSize="21dp"
                        android:text="仗义的猴子"
                        android:layout_below="@+id/per_iv_image"
                        android:layout_centerHorizontal="true"
                        android:layout_marginTop="10dp"
                        android:textColor="#EE0000"/>

                </RelativeLayout>

            </RelativeLayout>

            <RelativeLayout
                android:id="@+id/per_score"
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:layout_below="@+id/per_image"
                android:layout_marginTop="10dp"
                android:background="#FFFFFF">
                <ImageView
                    android:id="@+id/per_iv_score"
                    android:layout_width="30dp"
                    android:layout_height="30dp"
                    android:src="@mipmap/jifen"
                    android:layout_marginLeft="15dp"
                    android:layout_centerVertical="true"
                    />

                <TextView
                    android:id="@+id/per_tv_score"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_toRightOf="@+id/per_iv_score"
                    android:textSize="18dp"
                    android:layout_marginLeft="13dp"
                    android:layout_centerVertical="true"
                    android:text="我的积分"/>

            </RelativeLayout>

            <RelativeLayout
                android:id="@+id/per_tradedetail"
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:layout_below="@+id/per_score"
                android:layout_marginTop="10dp"
                android:background="#FFFFFF">
                <ImageView
                    android:id="@+id/per_iv_tradedetail"
                    android:layout_width="30dp"
                    android:layout_height="30dp"
                    android:src="@mipmap/jiaoyi"
                    android:layout_marginLeft="15dp"
                    android:layout_centerVertical="true"
                    />

                <TextView
                    android:id="@+id/per_tv_tradedetail"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_toRightOf="@+id/per_iv_tradedetail"
                    android:textSize="18dp"
                    android:layout_marginLeft="13dp"
                    android:layout_centerVertical="true"
                    android:text="交易详情"/>

            </RelativeLayout>

            <RelativeLayout
                android:id="@+id/per_donatedetail"
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:layout_below="@+id/per_tradedetail"
                android:layout_marginTop="10dp"
                android:background="#FFFFFF">
                <ImageView
                    android:id="@+id/per_iv_donatedetail"
                    android:layout_width="30dp"
                    android:layout_height="30dp"
                    android:src="@mipmap/donate"
                    android:layout_marginLeft="15dp"
                    android:layout_centerVertical="true"
                    />

                <TextView
                    android:id="@+id/per_tv_donatedetail"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_toRightOf="@+id/per_iv_donatedetail"
                    android:textSize="18dp"
                    android:layout_marginLeft="13dp"
                    android:layout_centerVertical="true"
                    android:text="捐赠信息"/>

            </RelativeLayout>

            <RelativeLayout
                android:id="@+id/per_modifyaddress"
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:layout_below="@+id/per_donatedetail"
                android:layout_marginTop="10dp"
                android:background="#FFFFFF">
                <ImageView
                    android:id="@+id/per_iv_modifyaddress"
                    android:layout_width="30dp"
                    android:layout_height="30dp"
                    android:src="@mipmap/address"
                    android:layout_marginLeft="15dp"
                    android:layout_centerVertical="true"
                    />

                <TextView
                    android:id="@+id/per_tv_modifyaddress"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_toRightOf="@+id/per_iv_modifyaddress"
                    android:textSize="18dp"
                    android:layout_marginLeft="13dp"
                    android:layout_centerVertical="true"
                    android:text="修改地址"/>

            </RelativeLayout>

            <RelativeLayout
                android:id="@+id/per_login"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/per_modifyaddress"
                android:layout_marginTop="15dp"
                android:layout_marginRight="20dp"
                android:layout_marginLeft="20dp">

                <Button
                    android:id="@+id/per_bt_login"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="登录"
                    android:textSize="23sp"
                    android:background="#BFEFFF"
                    />

            </RelativeLayout>

        </RelativeLayout>

    </ScrollView>
</RelativeLayout>


text:
import React from 'react';
import { connect } from 'react-redux';
import { Posts } from '../../components/List/Posts';

import {
  ActionPostPage
} from '../../actions';

export default connect(
  (state) => ({
    posts: state['homePage'].getIn(['posts']).toJS(),
  }),
  (dispatch) => ({
  	onPostClick: (post) => {
      // console.log(post);
  		dispatch(ActionPostPage.Goto(dispatch, {post: post}));
  	},
  })
)(Posts);

redpajama_set_name: RedPajamaGithub


text:
{% extends "base.html" %}

{% block title %}Change {{project.name}} on GitBug{% endblock %}

{% block header %}

{{project.name}}

Created on {{project.created_date|date:"jS F Y"}}

{% endblock %}

{% block content %}

{% if owner %}

<form action="" method="post" id="changeproject">

        URL
        <input type="text" name="url" id="url" class="txt" value="{% if project.url %}{{project.url}}{% endif %}"/>

Must be a valid URL

        Description
        <textarea id="description" name="description">{% if project.description %}{{project.description}}{% endif %}</textarea>

First fifteen words are shown on the project list, the rest is shown on the project page

        Other users
        <textarea id="other_users" name="other_users">{% for user in project.other_users %}{% if user %}{{user}} {% endif %}{% endfor %}</textarea>

Google email addresses separated by spaces

    <input type="submit" value="Change" class="btn"/>
</form>

{% endif %}

{% endblock %}


text:
/**
 * @license Highcharts JS v10.2.1 (2022-08-29)
 * @module highcharts/modules/treemap
 * @requires highcharts
 *
 * (c) 2014-2021 Highsoft AS
 * Authors: Jon Arild Nygard / Oystein Moseng
 *
 * License: www.highcharts.com/license
 */
'use strict';
import Highcharts from '../../Core/Globals.js';
import '../../Series/Treemap/TreemapSeries.js';
import Breadcrumbs from '../../Extensions/Breadcrumbs.js';
var G = Highcharts;
G.Breadcrumbs = Breadcrumbs;


text:
require 'spec_helper'

module Spice
  describe DataBag do

  end
end


text:
Boundary Event SDK Distribution File System Layout
-------------------------------------------------

Description of the distribution layout of a distribution.

Environment Variables
---------------------

BOUNDARY_SDK_APP_DIR - Directory that contains the application JAR file(s)
BOUNDARY_SDK_ETC_DIR - Directory that contains all of the configuration
BOUNDARY_SDK_JAR_DIR - Directory with all the jars the SDK is dependent upon
BOUNDARY_SDK_LOG_DIR - Directory to write the standard out and standard error logs
BOUNDARY_SDK_PID_DIR - Directory to write the process Id when running as a daemon

Tar or Zip Archive
------------------

```
boundary-event-sdk
   +   boundary-event-sdk-XX.YY.ZZ.jar
   +-- bin
       + bevent
       + beventd
       + beventapp
       + bmibc
       + send-syslog
       + send-v1-trap
       + send-v2c-trap
   +-- docs
       +--apidoc
       +--site
   +-- etc
       + boundary-event-sdk
       + event-routes.xml
   +-- lib
       + <dependent jar files>
   +-- log
       + boundary-event-sdk.log
```

RHEL/CentOS RPM
---------------

```
/
  +-- usr/bin
      + bevent
      + beventd
      + beventapp
      + bmibc
      + send-syslog
      + send-v1-trap
      + send-v2c-trap
  +-- etc/besdk
      + besdk.conf
      + event-routes.xml
  +-- etc/init.d
      + beventd
  +-- usr/share/besdk
      + <dependent jar files>
  +-- var/run
      + beventd.pid
  +-- usr/share/man/man1
      + beventd.1.gz


text:
package org.apache.qpid.jms.policy;

import jakarta.jms.ObjectMessage;

import org.apache.qpid.jms.JmsDestination;

/**
 * Defines the interface for a policy object that controls what types of message
 * content are permissible when the body of an incoming ObjectMessage is being
 * deserialized.
 */
public interface JmsDeserializationPolicy {

    JmsDeserializationPolicy copy();

    /**
     * Returns whether the given class is a trusted type and can be deserialized
     * by the client when calls to {@link ObjectMessage#getObject()} are made.
     *
     * @param destination
     *      the Destination for the message containing the type to be deserialized.
     * @param clazz
     *      the Type of the object that is about to be read.
     *
     * @return true if the type is trusted or false if not.
     */
    boolean isTrustedType(JmsDestination destination, Class<?> clazz);

}


text:
from django.db import models
from simple_history.models import HistoricalRecords

class DoYouKnow(models.Model):
    pass

class WhatIMean(DoYouKnow):
    pass

class Yar(models.Model):
    what = models.ForeignKey(WhatIMean)
    history = HistoricalRecords()


text:
<?php get_header(); ?>

	<?php do_action('foundationPress_before_content'); ?>

		<article <?php post_class() ?> id="post-<?php the_ID(); ?>">

<?php the_title(); ?>

			<?php do_action('foundationPress_page_before_entry_content'); ?>

			<?php
				if (isset($_GET['cid']) && $_GET['cid']) {
					$args = array('ID'=>$_GET['cid']);
					//$the_query = get_post($_GET['cid']);
					echo "
";
					//echo print_r($the_query);
					echo "
";
					$post_id = $_GET['cid'];
					$queried_post = get_post($post_id);
					$type = $queried_post->post_type;
					$status = $queried_post->post_status;
					if ($queried_post && $type == 'classmates' && $status == 'publish') { ?>
						<form id="post" class="acf-form" method="post" action="">
						<input class="button button-primary button-large" type="submit" value="Update the classmate Info!">
						<?php acf_form(array(
							'post_title'	=> false,
							'label_placement' => 'left',
							'form' => false,
							'post_id' => $queried_post->ID,
							'post_content' => false,

							'submit_value'	=> 'Update the classmate Info!'
						)); ?>
						<input class="button button-primary button-large" type="submit" value="Update the classmate Info!">
						</form>
					<?php }
					else {
						echo "Could not find the classmate id identified in the URL.";
					}
				}
				else {
					echo "Missing classmate id.";
				}?>

				<?php wp_link_pages(array('before' => '
' . __('Pages:', 'FoundationPress'), 'after' => '
' )); ?>

<?php the_tags(); ?>

			<?php do_action('foundationPress_page_before_comments'); ?>
			<?php comments_template(); ?>
			<?php do_action('foundationPress_page_after_comments'); ?>

	<?php do_action('foundationPress_after_content'); ?>

	<?php if ($queried_post) { ?>
		<?php if (has_post_thumbnail( $queried_post->ID ) ) {
			$post_thumbnail_id = get_post_thumbnail_id( $queried_post->ID );
			$image =  wp_get_attachment_url( $post_thumbnail_id, '' );
			if (!$image) {

			}

		}
		else {
			$image = get_no_image_link();
		}
		echo "";
		?>
	<?php } ?>

<?php get_footer(); ?>


text:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
   "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []>
<chapter id="scopes">
	<title>Faces Scoping Support</title>
	<para>
		JSF 2.0 introduced the concept of the Flash object and the @ViewScope; however, JSF 2.0 did not provide annotations accessing the Flash,
		 and CDI does not support the non-standard ViewScope by default. The Seam Faces module does both, in addition to adding a new @RenderScoped context.
         Beans stored in the Render Scope will survive until the next page is rendered. For the most part, beans stored in the ViewScope will survive as
         long as a user remains on the same page, and data in the JSF 2 Flash will survive as long as the flash survives).
	</para>

		<title>@RenderScoped</title>
	  <para>
            Beans placed in the @RenderScoped context are effectively scoped to, and live through but not after, "the next Render Response phase".
     </para>

      <para>
			You should think about using the Render scope if you want to store information that will be relevant to the user even after an action
			sends them to another view. For instance, when a user submits a form, you may want to invoke JSF navigation and redirect
			the user to another page in the site; if you needed to store a message to be displayed when the next page is rendered -but no longer-
			you would store that message in the RenderContext. Fortunately, Seam provides RenderScoped messages by default, via the
			<link linkend="faces.messages">Seam Messages API</link>.
		</para>

		<para>
			To place a bean in the Render scope, use the <literal>@org.jboss.seam.faces.context.RenderScoped</literal> annotation. This means that your
      bean will be stored in the  <literal>org.jboss.seam.context.RenderContext</literal> object until the next page is rendered,
      at which point the RenderScope will be cleared.
    </para>

<programlisting role="JAVA"><![CDATA[@RenderScoped
public class Bean {
	// ...
}]]></programlisting>
     <para>
       <literal>@RenderScoped</literal> beans are destroyed when the next <literal>JSF RENDER_RESPONSE</literal> phase
       ends, however, if a user has multiple browser windows open for the same user-session, multiple
       <literal>RenderContext</literal>s will be created, one for each incoming request. Seam Faces keeps
       track of which <literal>RenderContext</literal> belongs to each request, and will restore/destroy them appropriately.
       If there is more than one active <literal>RenderContext</literal> at the time when you issue a redirect, you will see
       a URL parameter <literal>?fid=...</literal> appended to the end of the outbound URL, this is to ensure the correct
       context is restored when the request is received by the server, and will not be present if only one context is active.
     </para>

	<caution>
				<para>
					If you want to use the Render Scope with custom navigation in your application,
					be sure to call <literal>ExternalContext.encodeRedirectURL(String url, Map<String, List<String>> queryParams)</literal>
					on any URL before using it to issue a redirect. This will ensure that the RenderContext ID is properly appended to the URL, enabling
					the RenderContext to be restored on the subsequent request. This is only necessary if issuing a Servlet Redirect; for the
                    cases where Faces non-redirecting navigation is used, no URL parameter is necessary, and the context will be destroyed at the end
                    of the current request.
				</para>
			</caution>

      <title>@Inject javax.faces.context.Flash flash</title>
      <para>
         JSF 2 does not provide proper system events to create a functional <literal>@FlashScoped</literal> context annotation integrated with CDI, so until
         a workaround can be found, or JSF 2 is enhanced, you can access the Flash via the @Inject annotation. For more information on the
               <ulink url="https://javaserverfaces.dev.java.net/nonav/docs/2.0/javadocs/javax/faces/context/Flash.html">JSF Flash</ulink>, read
               <ulink url="https://javaserverfaces.dev.java.net/nonav/docs/2.0/javadocs/javax/faces/context/Flash.html">this API doc</ulink>.
      </para>
         <programlisting role="JAVA">
public class Bean {
   @Inject private Flash flash;
   // ...
}</programlisting>

		<title>@ViewScoped</title>

		<para>
			To scope a bean to the View, use the <literal>@javax.faces.bean.ViewScoped</literal> annotation. This means that your bean will be stored in the
			<literal>javax.faces.component.UIViewRoot</literal> object associated with the view in which it was accessed. Each JSF view (faces-page) will store
			its own instance of the bean, just like each HttpServletRequest has its own instance of a @RequestScoped bean.
    </para>

			<programlisting role="JAVA">@ViewScoped
public class Bean {
	// ...
}</programlisting>
			<caution>
				<para>
					@ViewScoped beans are destroyed when the JSF UIViewRoot object is destroyed. This means that the
					life-span of @ViewScoped beans is dependent on the <literal>javax.faces.STATE_SAVING_METHOD</literal> employed by the application itself,
					but in general one can assume that the bean will live as long as the user remains on the same page.
				</para>
			</caution>

</chapter>


text:
* Every feature added
* Every bug fixed

## 0.2.0

### New/Modified Features
* Changed block execution so that it will work if cursor if placed directly before the opening of a block or after the closing of a block.
* Block execution temporarily highlights the area that was executed.

### Bug Fixes
* Fixed bug where once REPL was closed it could not be restarted without restarting Atom.

## 0.2.1

### New/Modified Features
* Block execution can detect the beginning and end of a Markdown code section containing Clojure and execute all of the Clojure code in the Markdown.

### Bug Fixes
* Fixed bug where an exception would be received if sending code to a REPL that was closed.
* Fixed many of the helper capabilities like printing documentation and running tests. The should have been executed in the namespace of the current file.

## 0.2.2

### Bug Fixes
* Fixed [very first filed issue](https://github.com/jasongilman/proto-repl/issues/1). Executing blocks ignores parentheses, etc inside strings or comments.

## 0.3.0

### New/Modified Features
* Added `protoRepl` global var and changed `executeCodeInNs` to allow users to write their own commands that can send code to the REPL.
* Added new keybindings for almost every command that should work for Windows, Linux, and OSX.

## 0.3.1

### Bug Fixes

* Fixing the way leiningen is started to address path issues.

## 0.4.0

### New/Modified Features

* Added ability to start Proto REPL outside of a Leiningen project. It uses a default project bundled with Proto REPL in this case.

## 0.4.1

### Bug Fixes

* Corrected keybindings in REPL help text.

## 0.5.0

### Bug Fixes

* Changed exit REPL keybinding from `ctrl-d` to `ctrl-, e` to avoid conflicting with Vim plugin.

### New/Modified Features

* Added the ability to execute the outermost block. (Thanks [@qwtel](https://github.com/jasongilman/proto-repl/pull/11)!)

## 0.5.1

### Bug Fixes

* Fixed problem with using Proto REPL on Windows.

## 0.6.0

### Bug Fixes

* Corrected process shutdown when a REPL window is closed.
* Fixed issue that made the REPL tab title show "untitled"

### New/Modified Features

* Proto REPL now uses nREPL for all communication with the REPL process. This is a much more standard way to send code to the REPL.
  * Allows interrupting a very long running command or infinite loop. Use ctrl-shift-c to send the interrupt.
* Added an option to `protoRepl` public execution functions to capture the result of execution in a callback. Added a function for parsing the result. This will allow the creation of extension packages to Proto REPL such as visualizations.
* Added setting to disable Clojure syntax in REPL.
* Refresh all command prints output to the REPL when it starts. Useful for immediate feedback when used in large projects.

## 0.7.0

### New/Modified Features

* Added ability to extend Proto REPL with code execution extensions. See proto-repl.coffee for more information. This feature allows the addition of extensions that can be used to visualize results from the REPL.

## 0.7.1

### Bug Fixes

* Forcing upgrade of nrepl-client to latest on github so that the newer version of bencode will be used. The previous version was causing the REPL to periodically hang when retrieving large requests.

## 0.8.0

### New/Modified Features

* Support for [proto-repl-charts](https://github.com/jasongilman/proto-repl-charts).

## 0.8.1

### Bug Fixes

* Fixed issue with refreshing the REPL when there's a compile error. The problem is displayed in the REPL now.

## 0.8.2

### New/Modified Features

* Adding alpha level support for [Atom Ink](https://github.com/JunoLab/atom-ink). Install the Atom Ink package and enable inline results in the Proto REPL settings. Results will be displayed inline as well as in the REPL.

## 0.8.3

### Bug Fixes

* Fixed #25. File names with slashes can now be loaded into the REPL.

## 0.9.0

### New/Modified Features

* Major rewrite of the REPL output and interaction to make it behave more like a traditional REPL:
  * REPL allows entering commands to execute in an entry area at the bottom. The upper area of the REPL is can not be modified. `shift+enter` executes code in the entry area.(#24, #10)
  * The REPL supports a history of commands (#23)
  * Executed code is echo'd in the REPL display area (#26)

### Bug Fixes

* Detects when clojure.tools.namespace is not available and displays error message.

## 0.10.0

### New/Modified Features

* Added config option to automatically pretty print results at the REPL. Uses [fipp](https://github.com/brandonbloom/fipp)
* Improved inline display of Clojure results by pretty printing results as secondary tree level.
* Added inline display of documentation when inline is enabled.

### Bug Fixes

* Fixed requiring of clojure.repl when listing namespace contents.

## 0.10.1

### Bug Fixes

* Fixed issue with trying to pretty print certain REPL output.

## 0.10.3

### Bug Fixes

* Fixed issue with refreshing the repl during a compilation problem.

## 0.10.4

### Bug Fixes

* Fixed issue #31. Reader conditionals can be evaluated either by sending them from a block of code or entered at the REPL.
* Fixed issue #32. Added callback for refreshing code. Running all tests will be triggered after a successful refresh.

## 0.11.0

### New/Modified Features

* Fixed #19 -  A REPL can be started from a specific project.clj file instead of the root one by opening the project.clj and pressing keyboard shortcut ctl-, shift-L (ctrl and comma together, release, then shift and L).

## 0.11.1

### Bug Fixes

* Fixed #34. Was not correctly setting the namespace when evaluating blocks and selections.

## 0.12.0

### New/Modified Features

* Fixed #36. Added option to refresh on REPL startup.
* Adding Autoloading of the current file as part of more experimental tests of inline results.

## 0.12.1

### Bug Fixes

* Updated for atom ink version 0.3.1

## 0.12.2

### Bug Fixes

* Fixed #41 Made Proto REPL detect if it was on pre-1.7 version of Clojure to use a different read-string call.

## 0.13.0

### New/Modified Features

* Fixed #17 - Added ability to connect to a remote nREPL. Thanks to [@geksilla](https://github.com/jasongilman/proto-repl/pull/45)
* Tweaking auto evaluation mode so that it doesn't display a marker and it correctly clears Atom ink inline results
* Taking inline mode out of beta.

## 0.14.0

### New/Modified Features

* Added updated implementation of displaying inline values from the REPL. The values are converted into a displayable tree where each child part can be expanded.
* Fixed #37 Selecting and opening a namespace alias now works.

### Bug Fixes

* Fixed an issue where if there was lots of standard output the returned value wouldn't be printed in the correct position within the output. This caused tests that produced lots of output to hide their results somewhere in the middle of the output.
* Fixed #50 with temporary change to a forked version of node-nrepl-client (jg-nrepl-client) that is published on npm.
* Fixed #43 opening files using internal Atom APIs instead of shelling out.

## 0.14.1

### Bug Fixes

* Fixed #57 - a problem where the REPL displayed everything twice when cider-nrepl middleware was included.
* Adding atom ink to the list of package dependencies.
* Fixed #13 (again) Fixed startup issues on Windows.

## 0.15.0

### Enhancements

* Fixed #51 - Proto REPL will now recursively search upwards for a project.clj file if it is opened in a subdirectory of a project.
* Added new feature for saving and displaying the values of local bindings. See https://github.com/jasongilman/proto-repl#saving-and-viewing-local-binding-values

## 0.15.1

### Bug Fixes

* Improvements to the display portion of save and display of local bindings.

## 0.15.2

### Bug Fixes

* Fixed #62 so that if the REPL is closed before the process has fully finished starting a new REPL can be opened.
* Fixed #63. Braces in regular expressions are now ignored when searching for s-expressions.
* Fixed #65. Added refresh call before running a single test file or a single test. This can be disabled through the Proto REPL settings.

## 0.16.0

### Enhancements

* Fixed #28. Added autocompletion support using Complement.

## 0.16.1

### Bug Fixes

* Fixed #68 - Avoids trying to find a project.clj if project folder is within "atom://.." directory.

## 0.16.2

### Bug Fixes

* Added more menu commands for opening the REPL from an open project.clj.

## 0.17.0

### New Features

* Added boot support.
* Changed to not display results inline or in repl when an execution extension is triggered.
* Updating default lein project to include latest version of proto repl charts.

## 1.0.0

Accidentally published as major instead of minor but oh well! Now is as good a time as any to say it's at 1.0.0.

### New Features

* Added preference option to choose leiningen or boot if both build files are present.
* Fixed #38 - Changed all commands that rely on selecting the full name for something to work if you just place your cursor on that name.

## 1.0.1

### New Features

* Added jsToEdn function for plugins to use.

## 1.0.2

### Bug fixes

* Changed some default settings to be better for new developers.
* Fixed #75 - REPL will keep track of the current namespace now.

## 1.0.3

* Changed boot startup so that it will use the dev profile.

## 1.1.0

* Added self hosted ClojureScript REPL.

## 1.1.1

* Fixing proto repl packaging problem

## 1.1.2

* Changing how Proto REPL tracks namespaces of the current REPL. Fixed issue where the repl was stuck after changing the namespace.

## 1.1.3

* Fixed issue in refresh handler that would cause it not to run all tests or not print refresh had completed.
* Added try catch to result handlers to help avoid cases where the REPL would stop working.

## 1.1.4

* Fixed #78 refreshing of code so it doesn't fail when user namespace is not available.

## 1.1.5

* Test change for Atom 1.7.

# 1.1.6

* #69 - Improving performance of tree view display.
* #69, #77 - Changing pretty printing to be off by default. You can reenable pretty printing by default in the settings or use `cmd-, p` to pretty print the results.
  * The automatic pretty printing didn't perform as well as I would like and wouldn't correctly display values for certain Clojure types. Pretty printing through `cmd-, p` uses the Clojure REPL to pretty print the results so it's correctly displayed.

# 1.1.7

* #89 - Allowing other completion providers to work with Proto REPL.

# 1.1.8

* #91 - Fixing Remote REPL connection error handling

# 1.1.9

* #98 - Fixing error loading with Atom Ink.
* #94 - Fixed display of documentation in the REPL.

# 1.1.10

* #56 - Changing keybindings from ctrl-, initiator to ctrl-alt-, to avoid preferences conflict. Leaving the old ones in place to avoid breaking existing users workflows.

# 1.1.11

* #110 - Fixed problem with starting Proto REPL default project REPL when Atom is running in dev mode.
* #102 - Added "proto-repl-repl" class to the text editor to allow custom styling. Added option to allow opening REPL in right pane or current pane.

# 1.2.0

* Added new extensions feature. This allows Proto REPL extensions to communicate with Proto REPL using a backchannel. Proto REPL Charts takes advantage of it for its new canvas drawing feature.

# 1.2.1

* #111 - Made small changes to error message in refresh.

# 1.3.0

* Added def buttons to the inline saved values.

# 1.3.1 to 1.3.3

* Updating library versions used in the default leiningen project so it uses the new Proto REPL library and other miscellaneous problems with the default leiningen project.

# 1.3.4

* Fixed #129 - saved values correctly captures the namespace.

# 1.4.0

* Added Ink Console for use as the default REPL output. Thanks to Camilo Roca for the prototyping and initial implementation.
* Fixed #133 - Namespace changing incorrectly back to user.

# 1.4.1

* Fixing several problems with the new Atom Ink Console usage.
  * Updating REPL instructions.
  * Fixing sizing of result output.
  * Fixing REPL history.

# 1.4.2

* Fixed #137 - REPL was not working if Atom Ink wasn't installed.

# 1.4.3

* Adding loading indicator. Thanks to Camilo Roca.
* Fixed #142 - Run all tests doesn't work when Ink Console is selected.
* Added callbacks for some Proto REPL events.


text:
If (
$env:BHPSModulePath -and
$env:BHBuildSystem -ne 'Unknown' -and
$env:BHBranchName -eq "master" -and
$env:BHModuleVersion -gt $env:BHGitHubLatestReleaseVersion -and
$env:BHModuleVersion -gt $env:BHPSGalleryLatestModuleVersion
)
{
    $Params = @{
        Path = "$ProjectRoot\AppVeyor\PSDeploy\PSGalleryModule.PSDeploy.ps1"
        Force = $true
        Recurse = $false # We keep psdeploy artifacts, avoid deploying those : )
    }

    Add-AppVeyorLog -Message 'Publish module on PSGallery' -Category 'Information'
    Invoke-PSDeploy @Verbose @Params

    # Publish to AppVeyor if we're in AppVeyor
    If (
        $env:BHPSModulePath -and
        $env:BHBuildSystem -eq 'AppVeyor'
    )
    {
        $Params = @{
            Path = "$ProjectRoot\AppVeyor\PSDeploy\AppVeyorModule.PSDeploy.ps1"
            Force = $true
            Recurse = $false # We keep psdeploy artifacts, avoid deploying those : )
        }

        Add-AppVeyorLog -Message 'Publish module as an AppVeyor artifact' -Category 'Information'
        Invoke-PSDeploy @Verbose @Params
    }

    # Create a new GitHub release
    Add-AppVeyorLog -Message 'Create a new GitHub release' -Category 'Information'
    $Release = New-GitHubRelease -username 'equelin' -repository $ENV:BHProjectName -token $ENV:GHToken -tag_name $env:BHModuleVersion -name $env:BHModuleVersion -draft $False

    # Show informations about the created release
    $Release | Format-Table id, tag_name, name, target_commitish -Autosize
}
Else
{
    $Details = @"
    Skipping deployment: To deploy, ensure that...
    You are in a known build system (Current: $ENV:BHBuildSystem)
    You are committing to the master branch (Current: $ENV:BHBranchName)
    The module version is greater than the latest GitHub release (Current: $ENV:BHModuleVersion GitHub:$env:BHGitHubLatestReleaseVersion)
    The module version is greater than the latest PSGallery version (Current: $ENV:BHModuleVersion GitHub:$env:BHPSGalleryLatestModuleVersion)
"@

    Add-AppVeyorLog -Message 'Skipping deployment' -Category 'Warning' -Details $Details
    <#
    Write-Host "[$env:BHBuildSystem]-[$env:BHProjectName] - Skipping deployment: To deploy, ensure that..." -ForegroundColor Magenta
    Write-Host "[$env:BHBuildSystem]-[$env:BHProjectName] - You are in a known build system (Current: $ENV:BHBuildSystem)" -ForegroundColor Magenta
    Write-Host "[$env:BHBuildSystem]-[$env:BHProjectName] - You are committing to the master branch (Current: $ENV:BHBranchName)" -ForegroundColor Magenta
    Write-Host "[$env:BHBuildSystem]-[$env:BHProjectName] - The module version is greater than the latest GitHub release (Current: $ENV:BHModuleVersion GitHub:$env:BHGitHubLatestReleaseVersion)" -ForegroundColor Magenta
    Write-Host "[$env:BHBuildSystem]-[$env:BHProjectName] - The module version is greater than the latest PSGallery version (Current: $ENV:BHModuleVersion GitHub:$env:BHPSGalleryLatestModuleVersion)" -ForegroundColor Magenta
    #>
}


text:
load_library :geomerative
java_import 'geomerative.RG'

# Create a reader for the object we are going to create in setup and use in draw
attr_reader :grp
def setup
  # Initialize the sketch
  size 600, 400
  frame_rate 24
  # VERY IMPORTANT: Always initialize the library in the setup
  RG.init(self)
  # Set colors
  fill(255, 102, 0)
  stroke(0)
  # Load the font file we want to use (the file must be in the data folder in
  # the sketch folder),  with the size 72 and the alignment CENTER
  @grp = RG.get_text('Hola Mundo!', 'FreeSans.ttf', 72, CENTER)
  smooth 4
end

def draw
  # Clean frame
  background(255)
  # Set the origin to draw in the middle of the sketch
  translate width / 2, height / 2
  # Transform at each frame the first letter with a PI/20 radians
  # rotation around the center of the first letter's center
  grp.children[0].rotate(PI / 20, grp.children[0].get_center)
  # Draw the group of shapes representing 'Hola Mundo!' on the PGraphics
  # canvas g (which is the default canvas of the sketch)
  grp.draw
end


text:
//----------------------------------------------------------------------------
//
// License:  LGPL
//
// See LICENSE.txt file in the top level directory for more details.
//
// Author:  David Burken
//
// Description:  Factory class definition for codec(encoder/decoder).
//
//----------------------------------------------------------------------------
// $Id$

#include <ossim/imaging/ossimCodecFactory.h>
#include <ossim/base/ossimKeywordlist.h>
#include <ossim/base/ossimKeywordNames.h>
#include <ossim/base/ossimRefPtr.h>
#include <ossim/base/ossimString.h>

#include <ossim/imaging/ossimJpegCodec.h>

#include <string>

ossimCodecFactory* ossimCodecFactory::theInstance = 0;

static const std::string TYPE_KW    = "type";

ossimCodecFactory::~ossimCodecFactory()
{}

ossimCodecFactory* ossimCodecFactory::instance()
{
   if ( !theInstance )
   {
      theInstance = new ossimCodecFactory();
   }
   return theInstance;
}
ossimCodecBase* ossimCodecFactory::createCodec(const ossimString& type)const
{
   ossimRefPtr<ossimCodecBase> result;

   if((type.downcase() == "jpeg") ||
      (type == "ossimJpegCodec"))
   {
      result =  new ossimJpegCodec();
   }

   return result.release();
}

ossimCodecBase* ossimCodecFactory::createCodec(const ossimKeywordlist& kwl, const char* prefix)const
{
   ossimString type = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
   ossimCodecBase* result = 0;
   if(!type.empty())
   {
      result = this->createCodec(type);
      if(result)
      {
         result->loadState(kwl, prefix);
      }
   }

   return result;
}

void ossimCodecFactory::getTypeNameList(std::vector<ossimString>& typeNames)const
{
   typeNames.push_back("jpeg");
}

ossimCodecFactory::ossimCodecFactory()
{}

ossimCodecFactory::ossimCodecFactory(const ossimCodecFactory& /* obj */ )
{}

const ossimCodecFactory& ossimCodecFactory::operator=(
   const ossimCodecFactory& /* rhs */)
{
   return *this;
}


text:
layout: post
title: "Implementing Caching in ASP.NET Core with SQL Server"
subtitle: "This article will discuss about implementing caching in ASP.NET Core using SQL Server Distributed Cache."
date: 2021-07-05 00:00:00
categories: [AspNetCore,Caching,SqlServer]
tags: [AspNetCore,Caching,SqlServer]
author: "Anuraj"
image: /assets/images/2021/07/caching_og.png
---
This article will discuss about implementing caching in ASP.NET Core using SQL Server Distributed Cache. Caching can improve the performance and scalability of an app, especially when the app is hosted by a cloud service or a server farm. In this implementation, you will be implementing distributed caching using SQL Server. In asp.net core distributed caching can be implemented with the help of `IDistributedCache` interface - you can start with MemoryCache in the development and in production you can switch to SQL Server or Redis or any other provider which implements `IDistributedCache` interface.

First you need to install the dotnet tool which helps you to setup the caching infrastructure. You can do this by running the command `dotnet tool install --global dotnet-sql-cache`. Once you install this tool, you can use this tool to create required table in SQL Server Database. You can do this using another command - `dotnet sql-cache create "Data Source=.;Initial Catalog=BlogsDb;User Id=sa;Password=Demo@123" dbo BlogsCache`. The command is `sql-cache` with `create` argument. And it requires the parameters like Connection string, Database Scheme and table name. Once you execute the command it will create a table like the following.

![New Cache Table]({{ site.url }}/assets/images/2021/07/cache_table_new.png)

If you don't want to create a tool for creating a table - you can use the following SQL Script.

{% highlight SQL %}
{% raw %}
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[BlogsCache](
	[Id] [nvarchar](449) NOT NULL,
	[Value] [varbinary](max) NOT NULL,
	[ExpiresAtTime] [datetimeoffset](7) NOT NULL,
	[SlidingExpirationInSeconds] [bigint] NULL,
	[AbsoluteExpiration] [datetimeoffset](7) NULL,
PRIMARY KEY CLUSTERED
(
	[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
	IGNORE_DUP_KEY = OFF,
	ALLOW_ROW_LOCKS = ON,
	ALLOW_PAGE_LOCKS = ON,
	OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
{% endraw %}
{% endhighlight %}

To use SQL Server Caching you need to install the package - `Microsoft.Extensions.Caching.SqlServer`. This package contains the implementation of `IDistributedCache` interface. You can install the nuget package by command - `dotnet add package Microsoft.Extensions.Caching.SqlServer`. Now you have completed the configuration aspects. Next you need to open the `Startup.cs` file, `ConfigureServices` method and add the following code - this code will be used to perform dependency injection of `IDistributedCache` interface to the controllers.

{% highlight CSharp %}
{% raw %}
services.AddDistributedSqlServerCache(options =>
{
    options.ConnectionString =
        Configuration.GetConnectionString("DefaultConnection");
    options.SchemaName = "dbo";
    options.TableName = "BlogsCache";
});
{% endraw %}
{% endhighlight %}

And now you're able to access `IDistributedCache` instance in controllers, like this.

{% highlight CSharp %}
{% raw %}
public class PostsController : ControllerBase
{
    private readonly ILogger<PostsController> _logger;
    private readonly IDistributedCache _distributedCache;

    public PostsController(ILogger<PostsController> logger, IDistributedCache distributedCache)
    {
        _logger = logger;
        _distributedCache = distributedCache;
    }
}
{% endraw %}
{% endhighlight %}

Here is simple caching pattern which helps to cache a list of items.

{% highlight CSharp %}
{% raw %}
[HttpGet]
public async Task<IActionResult> Get()
{
    var cachedPostsJson = await _distributedCache.GetStringAsync("Posts");
    if (cachedPostsJson == null)
    {
        _logger.LogInformation("Cache miss.");
        var posts = await _tinyLinksDbContext.Links.ToListAsync();
        var postsJson = JsonSerializer.Serialize(posts);
        await _distributedCache.SetStringAsync("Posts", postsJson);
        return Ok(posts);
    }

    _logger.LogInformation("Reading from Cache.");
    var cachedPosts = JsonSerializer.Deserialize<List<Post>>(cachedPostsJson);
    return Ok(cachedPosts);
}
{% endraw %}
{% endhighlight %}

Once you execute the code, the information stored in the table as binary. Since we didn't configured any expiry - default expiry time - 20 minutes (1200 seconds) is applied.

![Cached Data]({{ site.url }}/assets/images/2021/07/sql_cached_item.png)

You can configure expiration of items using `DistributedCacheEntryOptions` class, you need to create an instance of this class and use it while you're setting the cache. Here is the different expiration configuration you can set.

|Property | Description|
|----------|----------|
|AbsoluteExpiration|Gets or sets an absolute expiration date for the cache entry.|
|AbsoluteExpirationRelativeToNow|Gets or sets an absolute expiration time, relative to now.|
|SlidingExpiration|Gets or sets how long a cache entry can be inactive (e.g. not accessed) before it will be removed. This will not extend the entry lifetime beyond the absolute expiration (if set).|

Here is the updated code with expiration - which will expire the cache after one day based on the cache set.

{% highlight CSharp %}
{% raw %}
[HttpGet]
public async Task<IActionResult> Get()
{
    var cacheOptions = new DistributedCacheEntryOptions()
    {
        AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(1)
    };
    var cachedPostsJson = await _distributedCache.GetStringAsync("Posts");
    if (cachedPostsJson == null)
    {
        _logger.LogInformation("Cache miss.");
        var posts = await _tinyLinksDbContext.Links.ToListAsync();
        var postsJson = JsonSerializer.Serialize(posts);
        await _distributedCache.SetStringAsync("Posts", postsJson, cacheOptions);
        return Ok(posts);
    }

    _logger.LogInformation("Reading from Cache.");
    var cachedPosts = JsonSerializer.Deserialize<List<Post>>(cachedPostsJson);
    return Ok(cachedPosts);
}
{% endraw %}
{% endhighlight %}

You can remove the cache using `RemoveAsync()` method, you need to provide the key as the parameter.

If you're using ASP.NET Core MVC or Razor pages - ASP.NET Core provides a Distributed Cache Tag Helper -  provides the ability to dramatically improve the performance of your ASP.NET Core app by caching its content to a distributed cache source. This tag helper can be used with the key provided while you set the cache.

{% highlight CSharp %}
{% raw %}
<distributed-cache name="Posts">
    <!-- Mark up code to display blog posts -->
</distributed-cache>
{% endraw %}
{% endhighlight %}

This way you can implement Distributed Caching in ASP.NET Core with SQL Server. The advantage of this implementation or in fact any implementation of distributed caching in ASP.NET Core is you will be able to switch to any other provider without much code change. As I mentioned earlier for development environment you can use InMemory cache implementation and for production SQL Server.

Here are few links for you which might help you to find more details about different caching implementations and other helpful classes in ASP.NET Core.

* [Distributed caching in ASP.NET Core](https://docs.microsoft.com/en-us/aspnet/core/performance/caching/distributed?view=aspnetcore-5.0&WT.mc_id=DT-MVP-5002040){:target="_blank"}
* [Distributed Cache Tag Helper in ASP.NET Core](https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/built-in/distributed-cache-tag-helper?view=aspnetcore-5.0&WT.mc_id=DT-MVP-5002040){:target="_blank"}
* [Response Caching Middleware in ASP.NET Core](https://docs.microsoft.com/en-us/aspnet/core/performance/caching/middleware?view=aspnetcore-5.0&WT.mc_id=DT-MVP-5002040){:target="_blank"}

Happy Programming :)


text:
package org.apache.hadoop.yarn.server.nodemanager;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.atomic.AtomicBoolean;

import org.apache.hadoop.fs.FileContext;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.UnsupportedFileSystemException;
import org.apache.hadoop.yarn.api.protocolrecords.StartContainerRequest;
import org.apache.hadoop.yarn.api.protocolrecords.StartContainersRequest;
import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
import org.apache.hadoop.yarn.api.records.ApplicationId;
import org.apache.hadoop.yarn.api.records.ContainerId;
import org.apache.hadoop.yarn.api.records.ContainerLaunchContext;
import org.apache.hadoop.yarn.api.records.ContainerState;
import org.apache.hadoop.yarn.api.records.ContainerStatus;
import org.apache.hadoop.yarn.api.records.Priority;
import org.apache.hadoop.yarn.api.records.Resource;
import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hadoop.yarn.event.Dispatcher;
import org.apache.hadoop.yarn.exceptions.NMNotYetReadyException;
import org.apache.hadoop.yarn.exceptions.YarnException;
import org.apache.hadoop.yarn.exceptions.YarnRuntimeException;
import org.apache.hadoop.yarn.factories.RecordFactory;
import org.apache.hadoop.yarn.factory.providers.RecordFactoryProvider;
import org.apache.hadoop.yarn.server.api.ResourceTracker;
import org.apache.hadoop.yarn.server.api.protocolrecords.NMContainerStatus;
import org.apache.hadoop.yarn.server.api.protocolrecords.NodeHeartbeatRequest;
import org.apache.hadoop.yarn.server.api.protocolrecords.NodeHeartbeatResponse;
import org.apache.hadoop.yarn.server.api.protocolrecords.RegisterNodeManagerRequest;
import org.apache.hadoop.yarn.server.api.protocolrecords.RegisterNodeManagerResponse;
import org.apache.hadoop.yarn.server.api.records.NodeAction;
import org.apache.hadoop.yarn.server.nodemanager.containermanager.ContainerManagerImpl;
import org.apache.hadoop.yarn.server.nodemanager.containermanager.application.Application;
import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container;
import org.apache.hadoop.yarn.server.nodemanager.metrics.NodeManagerMetrics;
import org.apache.hadoop.yarn.server.security.ApplicationACLsManager;
import org.apache.hadoop.yarn.server.utils.YarnServerBuilderUtils;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class TestNodeManagerResync {
  static final File basedir =
      new File("target", TestNodeManagerResync.class.getName());
  static final File tmpDir = new File(basedir, "tmpDir");
  static final File logsDir = new File(basedir, "logs");
  static final File remoteLogsDir = new File(basedir, "remotelogs");
  static final File nmLocalDir = new File(basedir, "nm0");
  static final File processStartFile = new File(tmpDir, "start_file.txt")
    .getAbsoluteFile();

  static final RecordFactory recordFactory = RecordFactoryProvider
      .getRecordFactory(null);
  static final String user = "nobody";
  private FileContext localFS;
  private CyclicBarrier syncBarrier;
  private AtomicBoolean assertionFailedInThread = new AtomicBoolean(false);
  private AtomicBoolean isNMShutdownCalled = new AtomicBoolean(false);
  private final NodeManagerEvent resyncEvent =
      new NodeManagerEvent(NodeManagerEventType.RESYNC);

  @Before
  public void setup() throws UnsupportedFileSystemException {
    localFS = FileContext.getLocalFSFileContext();
    tmpDir.mkdirs();
    logsDir.mkdirs();
    remoteLogsDir.mkdirs();
    nmLocalDir.mkdirs();
    syncBarrier = new CyclicBarrier(2);
  }

  @After
  public void tearDown() throws IOException, InterruptedException {
    localFS.delete(new Path(basedir.getPath()), true);
    assertionFailedInThread.set(false);
  }

  @Test
  public void testKillContainersOnResync() throws IOException,
      InterruptedException, YarnException {
    TestNodeManager1 nm = new TestNodeManager1(false);

    testContainerPreservationOnResyncImpl(nm, false);
  }

  @Test
  public void testPreserveContainersOnResyncKeepingContainers() throws
      IOException,
      InterruptedException, YarnException {
    TestNodeManager1 nm = new TestNodeManager1(true);

    testContainerPreservationOnResyncImpl(nm, true);
  }

  @SuppressWarnings("unchecked")
  protected void testContainerPreservationOnResyncImpl(TestNodeManager1 nm,
      boolean isWorkPreservingRestartEnabled)
      throws IOException, YarnException, InterruptedException {
    YarnConfiguration conf = createNMConfig();
    conf.setBoolean(YarnConfiguration.RM_WORK_PRESERVING_RECOVERY_ENABLED,
        isWorkPreservingRestartEnabled);

    try {
      nm.init(conf);
      nm.start();
      ContainerId cId = TestNodeManagerShutdown.createContainerId();
      TestNodeManagerShutdown.startContainer(nm, cId, localFS, tmpDir,
          processStartFile);

      nm.setExistingContainerId(cId);
      Assert.assertEquals(1, ((TestNodeManager1) nm).getNMRegistrationCount());
      nm.getNMDispatcher().getEventHandler().handle(resyncEvent);
      try {
        syncBarrier.await();
      } catch (BrokenBarrierException e) {
      }
      Assert.assertEquals(2, ((TestNodeManager1) nm).getNMRegistrationCount());
      // Only containers should be killed on resync, apps should lie around.
      // That way local resources for apps can be used beyond resync without
      // relocalization
      Assert.assertTrue(nm.getNMContext().getApplications()
          .containsKey(cId.getApplicationAttemptId().getApplicationId()));
      Assert.assertFalse(assertionFailedInThread.get());
    }
    finally {
      nm.stop();
    }
  }

  // This test tests new container requests are blocked when NM starts from
  // scratch until it register with RM AND while NM is resyncing with RM
  @SuppressWarnings("unchecked")
  @Test(timeout=60000)
  public void testBlockNewContainerRequestsOnStartAndResync()
      throws IOException, InterruptedException, YarnException {
    NodeManager nm = new TestNodeManager2();
    YarnConfiguration conf = createNMConfig();
    nm.init(conf);
    nm.start();

    // Start the container in running state
    ContainerId cId = TestNodeManagerShutdown.createContainerId();
    TestNodeManagerShutdown.startContainer(nm, cId, localFS, tmpDir,
      processStartFile);

    nm.getNMDispatcher().getEventHandler()
      .handle(new NodeManagerEvent(NodeManagerEventType.RESYNC));
    try {
      syncBarrier.await();
    } catch (BrokenBarrierException e) {
    }
    Assert.assertFalse(assertionFailedInThread.get());
    nm.stop();
  }

  @SuppressWarnings("unchecked")
  @Test(timeout=10000)
  public void testNMshutdownWhenResyncThrowException() throws IOException,
      InterruptedException, YarnException {
    NodeManager nm = new TestNodeManager3();
    YarnConfiguration conf = createNMConfig();
    nm.init(conf);
    nm.start();
    Assert.assertEquals(1, ((TestNodeManager3) nm).getNMRegistrationCount());
    nm.getNMDispatcher().getEventHandler()
        .handle(new NodeManagerEvent(NodeManagerEventType.RESYNC));

    synchronized (isNMShutdownCalled) {
      while (isNMShutdownCalled.get() == false) {
        try {
          isNMShutdownCalled.wait();
        } catch (InterruptedException e) {
        }
      }
    }

    Assert.assertTrue("NM shutdown not called.",isNMShutdownCalled.get());
    nm.stop();
  }

  // This is to test when NM gets the resync response from last heart beat, it
  // should be able to send the already-sent-via-last-heart-beat container
  // statuses again when it re-register with RM.
  @Test
  public void testNMSentContainerStatusOnResync() throws Exception {
    final ContainerStatus testCompleteContainer =
        TestNodeStatusUpdater.createContainerStatus(2, ContainerState.COMPLETE);
    final Container container =
        TestNodeStatusUpdater.getMockContainer(testCompleteContainer);
    NMContainerStatus report =
        createNMContainerStatus(2, ContainerState.COMPLETE);
    when(container.getNMContainerStatus()).thenReturn(report);
    NodeManager nm = new NodeManager() {
      int registerCount = 0;

      @Override
      protected NodeStatusUpdater createNodeStatusUpdater(Context context,
          Dispatcher dispatcher, NodeHealthCheckerService healthChecker) {
        return new TestNodeStatusUpdaterResync(context, dispatcher,
          healthChecker, metrics) {
          @Override
          protected ResourceTracker createResourceTracker() {
            return new MockResourceTracker() {
              @Override
              public RegisterNodeManagerResponse registerNodeManager(
                  RegisterNodeManagerRequest request) throws YarnException,
                  IOException {
                if (registerCount == 0) {
                  // first register, no containers info.
                  try {
                    Assert.assertEquals(0, request.getNMContainerStatuses()
                      .size());
                  } catch (AssertionError error) {
                    error.printStackTrace();
                    assertionFailedInThread.set(true);
                  }
                  // put the completed container into the context
                  getNMContext().getContainers().put(
                    testCompleteContainer.getContainerId(), container);
                  getNMContext().getApplications().put(
                      testCompleteContainer.getContainerId()
                          .getApplicationAttemptId().getApplicationId(),
                      mock(Application.class));
                } else {
                  // second register contains the completed container info.
                  List<NMContainerStatus> statuses =
                      request.getNMContainerStatuses();
                  try {
                    Assert.assertEquals(1, statuses.size());
                    Assert.assertEquals(testCompleteContainer.getContainerId(),
                      statuses.get(0).getContainerId());
                  } catch (AssertionError error) {
                    error.printStackTrace();
                    assertionFailedInThread.set(true);
                  }
                }
                registerCount++;
                return super.registerNodeManager(request);
              }

              @Override
              public NodeHeartbeatResponse nodeHeartbeat(
                  NodeHeartbeatRequest request) {
                // first heartBeat contains the completed container info
                List<ContainerStatus> statuses =
                    request.getNodeStatus().getContainersStatuses();
                try {
                  Assert.assertEquals(1, statuses.size());
                  Assert.assertEquals(testCompleteContainer.getContainerId(),
                    statuses.get(0).getContainerId());
                } catch (AssertionError error) {
                  error.printStackTrace();
                  assertionFailedInThread.set(true);
                }

                // notify RESYNC on first heartbeat.
                return YarnServerBuilderUtils.newNodeHeartbeatResponse(1,
                  NodeAction.RESYNC, null, null, null, null, 1000L);
              }
            };
          }
        };
      }
    };
    YarnConfiguration conf = createNMConfig();
    nm.init(conf);
    nm.start();

    try {
      syncBarrier.await();
    } catch (BrokenBarrierException e) {
    }
    Assert.assertFalse(assertionFailedInThread.get());
    nm.stop();
  }

  // This can be used as a common base class for testing NM resync behavior.
  class TestNodeStatusUpdaterResync extends MockNodeStatusUpdater {
    public TestNodeStatusUpdaterResync(Context context, Dispatcher dispatcher,
        NodeHealthCheckerService healthChecker, NodeManagerMetrics metrics) {
      super(context, dispatcher, healthChecker, metrics);
    }
    @Override
    protected void rebootNodeStatusUpdaterAndRegisterWithRM() {
      try {
        // Wait here so as to sync with the main test thread.
        super.rebootNodeStatusUpdaterAndRegisterWithRM();
        syncBarrier.await();
      } catch (InterruptedException e) {
      } catch (BrokenBarrierException e) {
      } catch (AssertionError ae) {
        ae.printStackTrace();
        assertionFailedInThread.set(true);
      }
    }
  }

  private YarnConfiguration createNMConfig() {
    YarnConfiguration conf = new YarnConfiguration();
    conf.setInt(YarnConfiguration.NM_PMEM_MB, 5*1024); // 5GB
    conf.set(YarnConfiguration.NM_ADDRESS, "127.0.0.1:12345");
    conf.set(YarnConfiguration.NM_LOCALIZER_ADDRESS, "127.0.0.1:12346");
    conf.set(YarnConfiguration.NM_LOG_DIRS, logsDir.getAbsolutePath());
    conf.set(YarnConfiguration.NM_REMOTE_APP_LOG_DIR,
      remoteLogsDir.getAbsolutePath());
    conf.set(YarnConfiguration.NM_LOCAL_DIRS, nmLocalDir.getAbsolutePath());
    conf.setLong(YarnConfiguration.NM_LOG_RETAIN_SECONDS, 1);
    return conf;
  }

  class TestNodeManager1 extends NodeManager {

    private int registrationCount = 0;
    private boolean containersShouldBePreserved;
    private ContainerId existingCid;

    public TestNodeManager1(boolean containersShouldBePreserved) {
      this.containersShouldBePreserved = containersShouldBePreserved;
    }

    public void setExistingContainerId(ContainerId cId) {
      existingCid = cId;
    }

    @Override
    protected NodeStatusUpdater createNodeStatusUpdater(Context context,
        Dispatcher dispatcher, NodeHealthCheckerService healthChecker) {
      return new TestNodeStatusUpdaterImpl1(context, dispatcher,
          healthChecker, metrics);
    }

    public int getNMRegistrationCount() {
      return registrationCount;
    }

    class TestNodeStatusUpdaterImpl1 extends MockNodeStatusUpdater {

      public TestNodeStatusUpdaterImpl1(Context context, Dispatcher dispatcher,
          NodeHealthCheckerService healthChecker, NodeManagerMetrics metrics) {
        super(context, dispatcher, healthChecker, metrics);
      }

      @Override
      protected void registerWithRM() throws YarnException, IOException {
        super.registerWithRM();
        registrationCount++;
      }

      @Override
      protected void rebootNodeStatusUpdaterAndRegisterWithRM() {
        ConcurrentMap<ContainerId, org.apache.hadoop.yarn.server.nodemanager
        .containermanager.container.Container> containers =
            getNMContext().getContainers();
        try {
          try {
            if (containersShouldBePreserved) {
              Assert.assertFalse(containers.isEmpty());
              Assert.assertTrue(containers.containsKey(existingCid));
              Assert.assertEquals(ContainerState.RUNNING,
                  containers.get(existingCid)
                  .cloneAndGetContainerStatus().getState());
            } else {
              // ensure that containers are empty or are completed before
              // restart nodeStatusUpdater
              if (!containers.isEmpty()) {
                Assert.assertEquals(ContainerState.COMPLETE,
                    containers.get(existingCid)
                        .cloneAndGetContainerStatus().getState());
              }
            }
            super.rebootNodeStatusUpdaterAndRegisterWithRM();
          }
          catch (AssertionError ae) {
            ae.printStackTrace();
            assertionFailedInThread.set(true);
          }
          finally {
            syncBarrier.await();
          }
        } catch (InterruptedException e) {
        } catch (BrokenBarrierException e) {
        } catch (AssertionError ae) {
          ae.printStackTrace();
          assertionFailedInThread.set(true);
        }
      }
    }
  }

  class TestNodeManager2 extends NodeManager {

    Thread launchContainersThread = null;
    @Override
    protected NodeStatusUpdater createNodeStatusUpdater(Context context,
        Dispatcher dispatcher, NodeHealthCheckerService healthChecker) {
      return new TestNodeStatusUpdaterImpl2(context, dispatcher,
        healthChecker, metrics);
    }

    @Override
    protected ContainerManagerImpl createContainerManager(Context context,
        ContainerExecutor exec, DeletionService del,
        NodeStatusUpdater nodeStatusUpdater, ApplicationACLsManager aclsManager,
        LocalDirsHandlerService dirsHandler) {
      return new ContainerManagerImpl(context, exec, del, nodeStatusUpdater,
        metrics, aclsManager, dirsHandler){
        @Override
        public void setBlockNewContainerRequests(
            boolean blockNewContainerRequests) {
          if (blockNewContainerRequests) {
            // start test thread right after blockNewContainerRequests is set
            // true
            super.setBlockNewContainerRequests(blockNewContainerRequests);
            launchContainersThread = new RejectedContainersLauncherThread();
            launchContainersThread.start();
          } else {
            // join the test thread right before blockNewContainerRequests is
            // reset
            try {
              // stop the test thread
              ((RejectedContainersLauncherThread) launchContainersThread)
                .setStopThreadFlag(true);
              launchContainersThread.join();
              ((RejectedContainersLauncherThread) launchContainersThread)
              .setStopThreadFlag(false);
              super.setBlockNewContainerRequests(blockNewContainerRequests);
            } catch (InterruptedException e) {
              e.printStackTrace();
            }
          }
        }
      };
    }

    class TestNodeStatusUpdaterImpl2 extends MockNodeStatusUpdater {

      public TestNodeStatusUpdaterImpl2(Context context, Dispatcher dispatcher,
          NodeHealthCheckerService healthChecker, NodeManagerMetrics metrics) {
        super(context, dispatcher, healthChecker, metrics);
      }

      @Override
      protected void rebootNodeStatusUpdaterAndRegisterWithRM() {
        ConcurrentMap<ContainerId, org.apache.hadoop.yarn.server.nodemanager
        .containermanager.container.Container> containers =
            getNMContext().getContainers();

        try {
          // ensure that containers are empty before restart nodeStatusUpdater
          if (!containers.isEmpty()) {
            for (Container container: containers.values()) {
              Assert.assertEquals(ContainerState.COMPLETE,
                  container.cloneAndGetContainerStatus().getState());
            }
          }
          super.rebootNodeStatusUpdaterAndRegisterWithRM();
          // After this point new containers are free to be launched, except
          // containers from previous RM
          // Wait here so as to sync with the main test thread.
          syncBarrier.await();
        } catch (InterruptedException e) {
        } catch (BrokenBarrierException e) {
        } catch (AssertionError ae) {
          ae.printStackTrace();
          assertionFailedInThread.set(true);
        }
      }
    }

    class RejectedContainersLauncherThread extends Thread {

      boolean isStopped = false;
      public void setStopThreadFlag(boolean isStopped) {
        this.isStopped = isStopped;
      }

      @Override
      public void run() {
        int numContainers = 0;
        int numContainersRejected = 0;
        ContainerLaunchContext containerLaunchContext =
            recordFactory.newRecordInstance(ContainerLaunchContext.class);
        try {
          while (!isStopped && numContainers < 10) {
            StartContainerRequest scRequest =
                StartContainerRequest.newInstance(containerLaunchContext,
                  null);
            List<StartContainerRequest> list = new ArrayList<StartContainerRequest>();
            list.add(scRequest);
            StartContainersRequest allRequests =
                StartContainersRequest.newInstance(list);
            System.out.println("no. of containers to be launched: "
                + numContainers);
            numContainers++;
            try {
              getContainerManager().startContainers(allRequests);
            } catch (YarnException e) {
              numContainersRejected++;
              Assert.assertTrue(e.getMessage().contains(
                "Rejecting new containers as NodeManager has not" +
                " yet connected with ResourceManager"));
              Assert.assertEquals(NMNotYetReadyException.class.getName(), e
                .getClass().getName());
            } catch (IOException e) {
              e.printStackTrace();
              assertionFailedInThread.set(true);
            }
          }
          // no. of containers to be launched should equal to no. of
          // containers rejected
          Assert.assertEquals(numContainers, numContainersRejected);
        } catch (AssertionError ae) {
          assertionFailedInThread.set(true);
        }
      }
    }
  }

  class TestNodeManager3 extends NodeManager {

    private int registrationCount = 0;

    @Override
    protected NodeStatusUpdater createNodeStatusUpdater(Context context,
        Dispatcher dispatcher, NodeHealthCheckerService healthChecker) {
      return new TestNodeStatusUpdaterImpl3(context, dispatcher, healthChecker,
          metrics);
    }

    public int getNMRegistrationCount() {
      return registrationCount;
    }

    @Override
    protected void shutDown() {
      synchronized (isNMShutdownCalled) {
        isNMShutdownCalled.set(true);
        isNMShutdownCalled.notify();
      }
    }

    class TestNodeStatusUpdaterImpl3 extends MockNodeStatusUpdater {

      public TestNodeStatusUpdaterImpl3(Context context, Dispatcher dispatcher,
          NodeHealthCheckerService healthChecker, NodeManagerMetrics metrics) {
        super(context, dispatcher, healthChecker, metrics);
      }

      @Override
      protected void registerWithRM() throws YarnException, IOException {
        super.registerWithRM();
        registrationCount++;
        if (registrationCount > 1) {
          throw new YarnRuntimeException("Registration with RM failed.");
        }
      }
    }}

  public static NMContainerStatus createNMContainerStatus(int id,
      ContainerState containerState) {
    ApplicationId applicationId = ApplicationId.newInstance(0, 1);
    ApplicationAttemptId applicationAttemptId =
        ApplicationAttemptId.newInstance(applicationId, 1);
    ContainerId containerId = ContainerId.newContainerId(applicationAttemptId, id);
    NMContainerStatus containerReport =
        NMContainerStatus.newInstance(containerId, containerState,
          Resource.newInstance(1024, 1), "recover container", 0,
          Priority.newInstance(10), 0);
    return containerReport;
  }
}