text:
![Apache Fortress](images/ApacheFortressLogo_FINAL_SM.png "Apache Fortress")

Role-Based Access Control (RBAC)
-------------------------------------------------------------------------------
# LICENSE

   Licensed to the Apache Software Foundation (ASF) under one
   or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
   regarding copyright ownership.  The ASF licenses this file
   to you under the Apache License, Version 2.0 (the
   "License"); you may not use this file except in compliance
   with the License.  You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing,
   software distributed under the License is distributed on an
   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   KIND, either express or implied.  See the License for the
   specific language governing permissions and limitations
   under the License.

-------------------------------------------------------------------------------
# Overview

 * FORTRESS, a sub-project of the Apache Directory, is a standards-based access management system, written in Java, that provides
  role-based access control, delegated administration and password policy services with LDAP.
 * This repo is contains the Apache Fortress Core component.
 ![Apache Fortress Core System Architecture](images/fortress-core-system-arch.png "Apache Fortress Core System Architecture")
 * There are three other git repos that comprise the project:
   - [Realm for Apache Tomcat](https://github.com/apache/directory-fortress-realm)
   - [Rest/JSON APIs](https://github.com/apache/directory-fortress-enmasse)
   - [Web Admin Pages](https://github.com/apache/directory-fortress-commander)
 * For more information, visit http://directory.apache.org/fortress/

-------------------------------------------------------------------------------
## Table of Contents

 * Document Overview
 * Tips for first-time users.
 * SECTION 1.  Prerequisites
 * SECTION 2.  Download & Install.
 * SECTION 3.  Options for using Apache Fortress and LDAP.
 * SECTION 4.  Instructions for using Apache Fortress and ApacheDS LDAP server.
 * SECTION 5.  Instructions for using Apache Fortress and Symas OpenLDAP server.
 * SECTION 6.  Instructions for using Apache Fortress and native OpenLDAP server.
 * SECTION 7.  Instructions for configuring OpenLDAP.
 * SECTION 8.  Instructions for using Apache Fortress with OpenLDAP.
 * SECTION 9.  Instructions to integration test.
 * SECTION 10. Instructions to load policy data using Apache Fortress Load utility.
 * SECTION 11. Instructions to run the Apache Fortress Command Line Interpreter (CLI).
 * SECTION 12. Instructions to run the Apache Fortress Command Console.
 * SECTION 13. Instructions to build and test the Apache Fortress samples.
 * SECTION 14. Instructions to performance test.
 * SECTION 15. Instructions to encrypt LDAP passwords used in config files.

___________________________________________________________________________________
## Document Overview

This document contains instructions to download, install, test, and manage an LDAP server using the Apache Fortress Core.

___________________________________________________________________________________
##  Tips for first-time users

 * If you see **FORTRESS_HOME**, refer to the package [root folder](.).
 * If you see **OPENLDAP_HOME**, refer to the root of OpenLDAP binary installation folder, e.g. /opt/etc/openldap
 * This package uses Apache Maven to build and the [pom.xml](./pom.xml) is in the root folder.
 * The configuration subsystem manages coordinates to the targeted ldap server and more.  Here's how it works [README-CONFIG](./README-CONFIG.md).
 * This system runs within a multitenant context.  To learn how [README-MULTITENANCY](./README-MULTITENANCY.md).
 * Questions about usage may be directed to the mailing list:
   * http://mail-archives.apache.org/mod_mbox/directory-fortress/

-------------------------------------------------------------------------------
## SECTION 1. Prerequisites

Minimum hardware requirements to run Apache Fortress and LDAP server:
 * 2 Cores
 * 4GB RAM

Minimum software requirements:
 * git
 * Java SDK 8
 * Apache Maven3++

___________________________________________________________________________________
## SECTION 2. Download & Install

From Apache GIT Fortress-Core Software Repo:
 https://gitbox.apache.org/repos/asf?p=directory-fortress-core.git

1. Clone the SNAPSHOT:
 ```
 git clone  https://gitbox.apache.org/repos/asf/directory-fortress-core.git
 ```

 * or by specific version, e.g. 2.0.3

 ```
  git clone --branch 2.0.3  https://gitbox.apache.org/repos/asf/directory-fortress-core.git
 ```

2. Set Java and Maven home on machines.

3. From the FORTRESS_HOME root folder, enter the following command:

 ```
 mvn clean install
 ```

4. From the FORTRESS_HOME root folder, enter the following command:

 ```
 mvn javadoc:javadoc
 ```

5. View the generated document here: [./target/site/apidocs/overview-summary.html](./target/site/apidocs/overview-summary.html).

Install Notes:
 * The Apache Fortress [pom.xml](./pom.xml) may run without connection to Internet iff its dependencies are already present in local or intermediate maven repo.
 * Running ```mvn install``` calls out to maven-ant **init-fortress-config** task in [build.xml](./build.xml) to regenerate configuration artifacts (more info here: [README-CONFIG](./README-CONFIG.md)).

___________________________________________________________________________________
## SECTION 3.  Options for using Apache Fortress and LDAP server

This document describes three options to use Apache Fortress with:

1. ApacheDS LDAP server
 * **SECTION 4**. Apache Fortress and ApacheDS LDAP server
2. Symas OpenLDAP server
 * **SECTION 5**. Apache Fortress and Symas OpenLDAP server
3. Pre-existing OpenLDAP server
 * **SECTION 6**. Apache Fortress and native OpenLDAP server

*Options 1 & 2 are recommended for first-time users.  Option 3 is for advanced users.*
___________________________________________________________________________________
## SECTION 4. Instructions for using Apache Fortress and ApacheDS LDAP server

 * Follow these instructions: [README-QUICKSTART-APACHEDS](./README-QUICKSTART-APACHEDS.md)

___________________________________________________________________________________
## SECTION 5. Instructions for using Apache Fortress and Symas OpenLDAP server

 * Follow these instructions: [README-QUICKSTART-SLAPD](./README-QUICKSTART-SLAPD.md)

___________________________________________________________________________________
## SECTION 6. Instructions for using Apache Fortress and native OpenLDAP server

 Do these sections:

 * SECTION 2.  Download & Install
 * SECTION 7.  Instructions for configuring OpenLDAP
 * SECTION 8.  Instructions for using Apache Fortress with OpenLDAP
 * SECTION 9.  Instructions to integration test

___________________________________________________________________________________
## SECTION 7. Instructions for configuring OpenLDAP

1. Install OpenLDAP using preferred method.

 For example:

 A. On Debian systems: http://wiki.debian.org/LDAP/OpenLDAPSetup

 B. Ubuntu: https://help.ubuntu.com/community/OpenLDAPServer

 C. etc.

2. Copy fortress schema to openldap schema folder:

 ```
 cp FORTRESS_HOME/ldap/schema/fortress.schema OPENLDAP_HOME/etc/openldap/schema
 ```

3. Edit slapd.conf:

 ```
 vi OPENLDAP_HOME/etc/openldap/slapd.conf
 ```

4. Enable Fortress schema.

 Add to the top of the file:
 ```
 include OPENLDAP_HOME/etc/openldap/schema/fortress.schema
 ```

5. For password policy support, enable pwpolicy overlay.

 Add right before the ACL definitions:

 ```
 moduleload	 ppolicy.la
 ```

6. For Fortress audit support, enable slapo accesslog overlay.

 ```
 moduleload  accesslog.la
 ```

7. Enable Fortress default DB.

 ```
 # Default DB Settings
 database	mdb
 maxreaders 64
 maxsize<PHONE_NUMBER>
 suffix  "dc=example,dc=com"
 rootdn  "cn=Manager,dc=example,dc=com"
 rootpw  "{SSHA}pSOV2TpCxj2NMACijkcMko4fGrFopctU"

 index uidNumber,gidNumber,objectclass eq
 index cn,sn,ftObjNm,ftOpNm,ftRoleName,uid,ou eq,sub
 index ftId,ftPermName,ftRoles,ftUsers,ftRA,ftARA eq

 directory  "/var/openldap/dflt"
 overlay    accesslog
 logdb      "cn=log"
 dbnosync
 checkpoint	64 5
 ```

8. Enable Fortress slapo access log DB.

 ```
 # History DB Settings  (optional)
 database	 mdb
 maxreaders  64
 maxsize<PHONE_NUMBER>
 suffix      "cn=log"
 rootdn      "cn=Manager,cn=log"
 rootpw      "{SSHA}pSOV2TpCxj2NMACijkcMko4fGrFopctU"
 index objectClass,reqDN,reqAuthzID,reqStart,reqAttr eq
 directory	 "/var/openldap/hist"
 access to *
    by dn.base="cn=Manager,cn=log" write
 dbnosync
 checkpoint   64 5
 ```

9. Set the slapo access log usage policy on DB.

 ```
 # Audit Log Settings (optional)
 # note: the following settings may be tailored to your requirements:
 logops bind writes compare
 logoldattr ftModifier ftModCode ftModId ftRC ftRA ftARC ftARA ftCstr ftId ftPermName ftObjNm ftOpNm ftObjId ftGroups ftRoles ftUsers ftType
 logpurge 5+00:00 1+00:00
 ```

10. Enable slapo pwpolicy overlay.

 ```
 #######################################################################
 # PW Policy Settings
 #######################################################################
 # Enable the Password Policy overlay to enforce password policies on this database.
 overlay     ppolicy
 ppolicy_default "cn=PasswordPolicy,ou=Policies,dc=example,dc=com"
 ppolicy_use_lockout
 ppolicy_hash_cleartext
 ```

11. Add to OpenLDAP ACL's.

 ```
 ### ACLs
 access to dn="" by * read
 access to *
 	by self write
 	by users read
 	by anonymous auth
 	by sockurl="^ldapi:///$" write

 ### This one allows user to modify their own password (needed for pw policies):
 ### This also allows user to modify their own ftmod attributes (needed for audit):
 access to attrs=userpassword
          by self write
          by * auth
 ```

12. A few more for good measure.

 ```
 # Never allow anonymous binds:
 disallow bind_anon

 # Speeds up member list processing for ldap group operations:
 sortvals  roleOccupant

 # Convenience:
  gentlehup on

 # Sensible defaults:
 sizelimit 5000
 timelimit 60
 threads 8
 loglevel 32768

 ```

13. Create the dirs needed by the new slapd databases:

 ```
 mkdir /var/openldap/dflt
 mkdir /var/openldap/hist
 ```

14. Restart the slapd daemon.  Ensure there are no errors.

Config Notes:
 * Have a look at sample slapd.conf file: [./ldap/slapd.conf.src](./ldap/slapd.conf.src).

___________________________________________________________________________________
## SECTION 8. Instructions for using Apache Fortress with OpenLDAP

1. Copy FORTRESS_HOME/build.properties.example to build.properties and FORTRESS_HOME/slapd.properties.example to slapd.properties:

 ```
 cp build.properties.example build.properties
 cp slapd.properties.example slapd.properties
 ```

2. Edit the **slapd.properties** file.

 ```
 vi slapd.properties
 ```

3. Tell the runtime using OpenLDAP:

 ```
 ldap.server.type=openldap
 ```

4. Set the LDAP Host and port properties.  Either a valid host name or IP address can be used.  If you are running on the same platform as your LDAP server, localhost will do.

 ```
 host=localhost
 port=389
 ```

5. Set the suffix name and domain component.  These may be set according to your requirements.  For example **suffix.name=example** and **suffix.dc=com** turns into **dc=example,dc=com**.

 ```
 suffix.name=example
 suffix.dc=com
 ```

 * Optional - if a multi-level suffix needed, e.g. dc=foo, dc=example, dc=com.

 ```
  suffix.name=foo
  suffix.dc=example
  suffix.dc2=com
  suffix=dc=${suffix.name},dc=${suffix.dc},dc=${suffix.dc2}
 ```

6. Add to the file to enable LDAP connection pool parameters.

 ```
 # Here we are testing with slapd's root user.  Never do this in prod envs.
 # This value contains dn of service account that has read/write access to fortress LDAP DIT:
 root.dn=cn=Manager,${suffix}

 # This the admin password:
 cfg.root.pw=secret

 # Specify the min/max settings for ADMIN conn pool w/ both read & write connections to default DB:
 admin.min.conn=1

 # The optimal setting for max is much fewer than concurrent number of users on system.
 admin.max.conn=10

 # Specify the min/max settings for USER conn pool with permission to bind to user objects as self:
 user.min.conn=1

 # The optimal setting for max will be much fewer than concurrent number of users.
 user.max.conn=10
 ```

7. Enable the fortress audit and its connection pool.

 *This step is optional.*

 ```
 # If you don't have slapo-access log overlay enabled, disable the Fortress audit with this param.
 # 'true' turns it off.  The default is 'false'.
 disable.audit=false

 # This value contains dn of user that has read access to slapd access log database:
 log.root.dn=cn=Manager,${log.suffix}

 # This password is for same log user:
 cfg.log.root.pw=secret

 # The min/max settings for LOG pool w/ read permissions to slapo access log:
 log.min.conn=1

 # Very few needed because only used by AuditMgr during search operations:
 log.max.conn=3

 # Set more audit logger parameters (openldap only):
 log.suffix=cn=log

 # To enable slapd persistence on the following OpenLDAP operations:
 log.ops=logops search bind writes
 ```

8. Rebuild the configuration artifacts:

 ```
 mvn clean install
 ```

9. Perform an initial load to the target LDAP server:

 ```
 mvn install -Dload.file=./ldap/setup/refreshLDAPData.xml
 ```

  * Do not run this target with **refreshLDAPData.xml** on production systems as it deletes all nodes beneath the suffix before readding.

More usage notes of fortress build property files:
 * The defaults usually work.
 * The [build.properties.example]([build.properties.example) contains defaults for ApacheDS.  This file is required and will activate once renamed to **build.properties**.
 * The [slapd.properties.example](slapd.properties.example) is optional.  Use *only* when OpenLDAP is the target server.  Once renamed to **slapd.properties**, it will override any values found in the **build.properties** file.
 * Learn more about the configuration subsystem: [README-CONFIG](./README-CONFIG.md)
 * Learn more about what properties there are: [README-PROPERTIES](README-PROPERTIES.md).
 * Don't change the ant substitution parameters within the properties *unless you know what you're doing*.  These are are the settings inside of curly brackets, e.g. **${param1}**.

___________________________________________________________________________________
## SECTION 9. Instructions to integration test

1. From **FORTRESS_HOME** enter the following commands:

 ```
 mvn install -Dload.file=./ldap/setup/refreshLDAPData.xml
 mvn install -Dload.file=./ldap/setup/DelegatedAdminManagerLoad.xml
 ```

 These will build the Directory Information Tree, load the configuration node and security policy needed for integration testing.
 Never run in production environment as **refreshLDAPData.xml** tears down all nodes under the target suffix.

2. Next, from **FORTRESS_HOME** enter the following command:

 ```
 mvn -Dtest=FortressJUnitTest test
 ```

 Tests that all of the APIs and security functions work on your LDAP server.

3. Verify the tests worked:

 ```
 Tests run: Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 196 sec - in org.apache.directory.fortress.core.impl.FortressJUnitTest

 Results :

 Tests run: Failures: 0, Errors: 0, Skipped: 0

 [INFO]
 [INFO] --- maven-antrun-plugin:1.8:run (default) @ fortress-core ---
 [INFO] Executing tasks

 fortress-load:
 [INFO] Executed tasks
 [INFO] ------------------------------------------------------------------------
 [INFO] BUILD SUCCESS
 [INFO] ------------------------------------------------------------------------
 [INFO] Total time: 03:19 min
 [INFO] Finished at: 2016-01-07T09:28:18-06:00
 [INFO] Final Memory: 27M/532M
 [INFO] ------------------------------------------------------------------------
 ```

4. Rerun the tests to verify teardown APIs work:

 ```
 mvn -Dtest=FortressJUnitTest test
 ```

5. Verify that worked also:

 ```
 Tests run: Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 207.081 sec - in org.apache.directory.fortress.core.impl.FortressJUnitTest

 Results :

 Tests run: Failures: 0, Errors: 0, Skipped: 0

 [INFO]
 [INFO] --- maven-antrun-plugin:1.8:run (default) @ fortress-core ---
 [INFO] Executing tasks

 fortress-load:
 [INFO] Executed tasks
 [INFO] ------------------------------------------------------------------------
 [INFO] BUILD SUCCESS
 [INFO] ------------------------------------------------------------------------
 [INFO] Total time: 03:30 min
 [INFO] Finished at: 2016-01-07T09:33:11-06:00
 [INFO] Final Memory: 27M/531M
 [INFO] ------------------------------------------------------------------------
 ```
 Notice that more tests ran this time vs the first time, due to teardown.

6. You can now clear out the test data and policies by rerunning this command:

 ```
 mvn install -Dload.file=./ldap/setup/refreshLDAPData.xml
 ```

 Test Notes:
  * If tests complete without errors Apache Fortress works with your LDAP server.
  * These tests load thousands of objects into the target ldap server.  You should clear out the test data in the end.
  * Warning messages are negative tests in action.

___________________________________________________________________________________
## SECTION 10. Instructions to load policy data using Apache Fortress Load utility

 The Load utility is useful to create base policy configurations that need to be rerun many times in different test and production environments.
 For samples look here: [./ldap/setup](./ldap/setup).

1. Create a load file using examples from **FORTRESS_HOME**/ldap/setup folder.

 e.g. myLoadFile.xml

2. From **FORTRESS_HOME** folder, enter the following command:

 ```
 mvn install -Dload.file=./ldap/setup/myLoadFile.xml
 ```

Policy Load Notes:
 * This maven target executes **FortressAntTask** to automate data loads into the LDAP server using the Fortress APIs.
 * More info on ant load utility in the generated javadoc:
  * [./target/site/apidocs/org/apache/directory/fortress/core/ant/FortressAntTask.html](./target/site/apidocs/org/apache/directory/fortress/core/ant/FortressAntTask.html)

___________________________________________________________________________________
## SECTION 11. Instructions to run the Apache Fortress Command Line Interpreter (CLI)

 The CLI is useful for ad-hoc policy administration in runtime environments.

1. From **FORTRESS_HOME** enter the following command:

 ```
 mvn -Pcli test
  ```

2. Which starts the Fortress command line interpreter:

 ```
 CommandLineInterpreter:176 - Startup to interactive mode success...
 CommandLineInterpreter:183 - CLI function groups include admin, review, system, dadmin, group
 CommandLineInterpreter:185 - Enter one from above or 'q' to quit
 ```

3. Where subsequent commands can be performed.  For example to add a new user:

 ```
 admin auser -u testuser1 -p mypasword123 -o dev1
 2016-01-07 09:17:030 INFO  CommandLineInterpreter:1078 - arg:admin
 2016-01-07 09:17:030 INFO  CommandLineInterpreter:1078 - arg:auser
 2016-01-07 09:17:030 INFO  CommandLineInterpreter:1078 - arg:-u
 2016-01-07 09:17:030 INFO  CommandLineInterpreter:1078 - arg:testuser1
 2016-01-07 09:17:030 INFO  CommandLineInterpreter:1078 - arg:-p
 2016-01-07 09:17:030 INFO  CommandLineInterpreter:1078 - arg:-o
 2016-01-07 09:17:030 INFO  CommandLineInterpreter:1078 - arg:dev1
 2016-01-07 09:17:030 INFO  CommandLineInterpreter:487 - auser
 2016-01-07 09:17:030 INFO  CommandLineInterpreter:683 - command:auser was successful
 2016-01-07 09:17:030 INFO  CommandLineInterpreter:183 - CLI function groups include admin, review, system, dadmin, group
 2016-01-07 09:17:030 INFO  CommandLineInterpreter:185 - Enter one from above or 'q' to quit
 ```

4. Or to interrogate users:

 ```
 review fuser -u testuser1
 2016-01-07 09:18:042 INFO  CommandLineInterpreter:1078 - arg:review
 2016-01-07 09:18:042 INFO  CommandLineInterpreter:1078 - arg:fuser
 2016-01-07 09:18:042 INFO  CommandLineInterpreter:1078 - arg:-u
 2016-01-07 09:18:042 INFO  CommandLineInterpreter:1078 - arg:testuser1
 2016-01-07 09:18:042 INFO  CommandLineInterpreter:713 - fuser
 2016-01-07 09:18:042 INFO  CommandLineInterpreter:1443 - U   CTR  [0]
 2016-01-07 09:18:042 INFO  CommandLineInterpreter:1443 - U   UID  [testuser1]
 2016-01-07 09:18:042 INFO  CommandLineInterpreter:1443 - U   IID  [20ef2dfd-0b86-41a5-87d6-f7081e455d76]
 2016-01-07 09:18:042 INFO  CommandLineInterpreter:1443 - U   CN   [testuser1]
 2016-01-07 09:18:042 INFO  CommandLineInterpreter:1443 - U   DESC [null]
 2016-01-07 09:18:042 INFO  CommandLineInterpreter:1443 - U   OU   [dev1]
 2016-01-07 09:18:042 INFO  CommandLineInterpreter:1443 - U   SN   [testuser1]
 ```

5. Or perform any of the other APIs as a shell program, follow instructions in the command line interpreter reference manual, contained within the generated javadoc:
 * [./target/site/apidocs/org/apache/directory/fortress/core/cli/package-summary.html/package-summary.html](./target/site/apidocs/org/apache/directory/fortress/core/cli/package-summary.html)

___________________________________________________________________________________
## SECTION 12. Instructions to run the Apache Fortress Command Console

 The Command Console is an interactive program that is allows ad-hoc edit and reporting on data stored in LDAP server.

1. From **FORTRESS_HOME** enter the following command:

 ```
 mvn -Pconsole test
 ```

2. Is a menu-driven program.  Select option:

 ```
 CHOOSE FUNCTION:
 1. RBAC ADMIN MANAGER
 2. RBAC REVIEW MANAGER
 3. RBAC ACCESS MANAGER
 4. ARBAC ADMIN MANAGER
 5. ARBAC REVIEW MANAGER
 6. ARBAC ACCESS MANAGER
 7. PASSWORD POLICY MANAGER
 8. AUDIT MANAGER
 9. CONFIG MANAGER
 A. ENCRYPTION MANAGER
 B. GROUP MANAGER
 C. RBAC ACCELERATOR MANAGER
 Enter q or Q to quit
 ```

3. Option 1 performs Administrative operations:

 ```
CHOOSE ADMIN MANAGER FUNCTION:
 1.  Add User
 2.  Update User
 3.  Delete User
 4.  Unlock User
 5.  Lock User Account
 6.  Reset User Password
 7.  Change User Password
 8.  Add Perm Object
 9.  Add Perm Operation
 0.  Delete  Perm
 A.  Add Role
 B.  Update Role
 C.  Delete Role
 D.  Assign User to Role
 E.  Deassign User from Role
 F.  Grant Perm to Role
 G.  Revoke Perm from Role
 H.  Grant Perm to User
 I.  Revoke Perm from User
 J.  Add Role Inheritance
 K.  Remove Role Inheritance
 L.  Add Role Ascendant
 M.  Add Role Descendant
 N.  Add SSD Data Set
 O.  Add DSD Data Set
 Enter q or Q to return to previous menu
 ```

4. Option 2 performs Review operations:

 ```
 CHOOSE REVIEW MANAGER FUNCTION:
 0. Search Users
 1. Search Users by OU
 2. Get User by IID
 3. Read User
 4. Search Permissions
 5. Read Permissions
 6. Read Role
 7. Search Roles
 8. Perm Roles
 9. Perm Users
 A. Authorized Users
 B. Role Permissions
 C. Get Assigned Roles
 Enter q or Q to return to previous menu
 ```

5. Option 3 performs Access operations (for testing):

 ```
 CHOOSE ACCESS MANAGER FUNCTION:
 1. Authenticate
 2. Create Session
 3. Create Session Trusted
 4. Create Session with Roles Trusted
 5. Create Session with Props
 6. Check Access - RBAC
 7. Session Roles
 8. Add Active Role to Session
 9. Drop Active Role from Session
 0. Show User Data in Session
 A. Show UserId in Session
 B. Session Permissions
 Enter q or Q to return to previous menu
 ```

6. etc... for PW Policy, ARBAC, Groups.

___________________________________________________________________________________
## SECTION 13. Instructions to build and test the Apache Fortress samples

1. From **FORTRESS_HOME** enter the following command:

 ```
 mvn -Dtest=AllSamplesJUnitTest test
 ```

2. View and change the samples here:
 [./src/test/java/org/apache/directory/fortress/core/samples](./src/test/java/org/apache/directory/fortress/core/samples)

3. Compile and re-run samples to test your changes using:

 ```
 mvn -Dtest=AllSamplesJUnitTest test
 ```

4. Sample show how to use the APIs
 e.g. How to Grant a Permission to a Role:

 ```java
 AdminMgr adminMgr = AdminMgrFactory.createInstance(TestUtils.getContext());

 Role inRole = new Role(CreateRoleSample.TEST_ROLE_PREFIX + i);

 // Permissions contain Object to Operation mapping and once created can then be targeted for assignment to Role entities in ldap:
 Permission inPerm = new Permission(TEST_PERM_OBJECT, TEST_PERM_OPERATION_PREFIX + j);

 // This API grant a Permission to a Role:
 adminMgr.grantPermission(inPerm, inRole);
 ```

Sample Notes:
 * Test cases are simple and useful for learning how to code using Apache Fortress APIs.
 * Tests should complete without ERRORS.
 * These tests will load some records into the target ldap server.
 * The target may be run as many times as necessary and should be run at least twice to test the teardown.
 * The 2nd and subsequent times runs, it will tear down the data loaded during the prior run.

___________________________________________________________________________________
## SECTION 14. Instructions to performance test

 This section describes the Apache Fortress jmeter test programs.

1. Load the security policy and users required by the jmeter test routines:

 ```
 mvn install -Dload.file=./ldap/setup/LoadTestUsers.xml
 ```

2. The .jmx files located in [.src/test/jmeter](.src/test/jmeter) folder correspond to each test type:

 A. Fortress CheckAccess:
  [src/test/jmeter/ftCheckAccess.jmx](src/test/jmeter/ftCheckAccess.jmx)

 B. Fortress CreateSession:
  [src/test/jmeter/ftCreateSession.jmx](src/test/jmeter/ftCreateSession.jmx)

 C. Fortress SessionPermissions:
  [src/test/jmeter/ftSessionPerms.jmx](src/test/jmeter/ftSessionPerms.jmx)

 D. Accelerator CheckAccess:
  [src/test/jmeter/acCheckAccess.jmx](src/test/jmeter/acCheckAccess.jmx)

 E. Accelerator CreateSession:
  [src/test/jmeter/acCreateSession.jmx](src/test/jmeter/acCreateSession.jmx)

3. Setting the jmeter parameters.

 These settings affect the length, duration, and the number of threads:

 * **LoopController.continue_forever**: boolean value, if *false*, test duration is controlled by numbers of *loops* and *threads*.
 * **LoopController.loops**: integer value, contains the number of iterations each thread performs the test function.
 * **ThreadGroup.num_threads**: integer value, contains the number of threads to use in the test.
 * **ThreadGroup.ramp_time**: integer value, number of seconds for starting threads.  A rule of thumb, set to same as num_threads.

 For example:
 ```
 <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Fortress CreateSession" enabled="true">
     ...
     <elementProp name="ThreadGroup.main_controller" ...>
         <boolProp name="LoopController.continue_forever">false</boolProp>
         <stringProp name="LoopController.loops">1000</stringProp>
     </elementProp>
     <stringProp name="ThreadGroup.num_threads">10</stringProp>
     <stringProp name="ThreadGroup.ramp_time">10</stringProp>
     ...
 </ThreadGroup>
 ```

 This test will start ten threads in ten seconds.  Each thread executes the *createSession* function 1000 times before terminating.

4.  Run the tests.

 From **FORTRESS_HOME** folder, enter the following command from a system prompt:

 A. Fortress CheckAccess:
  ```
  mvn -Ploadtest-fortress jmeter:jmeter
  ```

 B. Fortress CreateSession:
  ```
  mvn -Ploadtest-fortress-createsess jmeter:jmeter
  ```

 C. Fortress SessionPermissions:
  ```
  mvn -Ploadtest-fortress-sessperms jmeter:jmeter
  ```

 D. Accelerator CheckAccess:
  ```
  mvn -Ploadtest-accel jmeter:jmeter
  ```

 E. Accelerator CreateSession:
  ```
  mvn -Ploadtest-accel-createsess jmeter:jmeter
  ```

 The tests will run and produce measurements for throughput and latency.

___________________________________________________________________________________
## SECTION 15. Instructions to encrypt LDAP passwords used in config files

If you need the passwords for LDAP service accounts to be encrypted before loading into Fortress properties files you can
use the 'encrypt' ant target.

1. From **FORTRESS_HOME** root folder, enter the following command from a system prompt:

 ```
 ant encrypt -Dparam1=secret
 encrypt:
      [echo] Encrypt a value
      [java] Encrypted value=wApnJUnuYZRBTF1zQNxX/Q==
 BUILD SUCCESSFUL
 Total time: 1 second
 ```

2. Copy the hashed value and paste it into the corresponding build.properties setting, e.g.:

 ```
 # This OpenLDAP admin root pass is bound for fortress.properties and was hashed using 'encrypt' target in build.xml:
 cfg.log.root.pw=wApnJUnuYZRBTF1zQNxX/Q==
 ```

 ___________________________________________________________________________________
 #### END OF README

repository: DalavanCloud/directory-fortress-core

repo_name: DalavanCloud/directory-fortress-core


text:
# get-in

[![Build Status](https://travis-ci.org/igorw/get-in.png)](https://travis-ci.org/igorw/get-in)

Functions for for hash map (assoc array) traversal.

When dealing with nested associative structures, traversing them can become
quite a pain. Mostly because of the amount of `isset` checking that is
necessary.

For example, to access a nested key `['foo']['bar']['baz']`, you must do
something like this:

```php
$baz = (isset($data['foo']['bar']['baz'])) ? $data['foo']['bar']['baz'] : null;
```

Enough already! `get-in` provides a better way:

```php
$baz = igorw\get_in($data, ['foo', 'bar', 'baz']);
```

## Installation

Through [composer](http://getcomposer.org):

```bash
$ composer require igorw/get-in:~1.0
```

## Usage

### get_in

Retrieve value from a nested structure using a list of keys:

```php
$users = [
    ['name' => 'Igor Wiedler'],
    ['name' => 'Jane Doe'],
    ['name' => 'Acme Inc'],
];

$name = igorw\get_in($users, [1, 'name']);
//= 'Jane Doe'
```

Non existent keys return null:

```php
$data = ['foo' => 'bar'];

$baz = igorw\get_in($data, ['baz']);
//= null
```
You can provide a default value that will be used instead of null:

```php
$data = ['foo' => 'bar'];

$baz = igorw\get_in($data, ['baz'], 'qux');
//= 'qux'
```
### update_in

Apply a function to the value at a particular location in a nested structure:

```php
$data = ['foo' => ['answer' => 42]];
$inc = function ($x) {
    return $x + 1;
};

$new = igorw\update_in($data, ['foo', 'answer'], $inc);
//= ['foo' => ['answer' => 43]]
```

You can variadically provide additional arguments for the function:

```php
$data = ['foo' => 'bar'];
$concat = function (/* $args... */) {
    return implode('', func_get_args());
};

$new = igorw\update_in($data, ['foo'], $concat, ' is the ', 'best');
//= ['foo' => 'bar is the best']
```

### assoc_in

Set a value at a particular location:

```php
$data = ['foo' => 'bar'];

$new = igorw\assoc_in($data, ['foo'], 'baz');
//= ['foo' => 'baz']
```

It will also set the value if it does not exist yet:

```php
$data = [];

$new = igorw\assoc_in($data, ['foo', 'bar'], 'baz');
//= ['foo' => ['bar' => 'baz']]
```

## Inspiration

The naming and implementation is inspired by the `get-in`, `update-in` and
`assoc-in` functions from [clojure](http://clojure.org).

license: MIT

repository: cgatherer/brtsy

branch_name: refs/heads/master

extension: md

gha_language: PHP

gha_license_id: MIT

license_type: permissive

repo_name: cgatherer/brtsy


text:
# Zhaochen Blog

>This is the [Blog](https://dawnotdown.github.io/) of Zhaochen,something about life or iOS-dev.

##### The following had posted:

date | title | content
---- | --- | ---
2018-3-1 | [CommandRoute](https://dawnotdown.github.io/2018/03/01/CommandRoute/)  | 手Y命令号路由系统
2018-2-1 | [Channel-Templatization](https://dawnotdown.github.io/2018/02/01/Channel-Templatization/)  | 手Y直播间模板化
2018-1-29 | [Channel-Modularization](https://dawnotdown.github.io/2018/01/29/Channel-Modularization/)  | 手Y直播间组件化
2017-12-18 | [Push](https://dawnotdown.github.io/2017/12/18/Push/) | 手Y推送
2016-11-29 |  [first-blog](https://dawnotdown.github.io/2016/11/29/first-blog/) | 第一篇


text:
# Plain-Terminal-Library

Ptlib is a cross platform, single header library which povides a layer of abstraction for raw input and graphics in the command line.

The goal is to provide a small set of functions that you can build upon.
input and graphics are as basic as it gets, but it hides away the boilerplate code.

the library should support windows, mac and linux.

branch_name: refs/heads/main


text:
# Modular Configuration Files

We have found that, for our larger and more complex systems, the deployment-specific
configuration files we were using had become large and unwieldy, requiring us to
either manage large files with duplicated configuration between them, or many
separate files which required us to remember the full set of files required for each
deployment.

To simplify this, we developed a system of "modular" config files.

## The Basics - File Hierarchy

Continuing the examples in the [Basic Config](Config.md) document, imagine that
we find that we need different config for our Knightrider simulations.

knightrider_chase.properties
```properties
VehicleConfig.ABSOLUTE_SPEED_LIMIT=150,KILOMETERS,HOURS
VehicleConfig.CarSimulation.NUMBER_OF_WHEELS=4
...
```

knightrider_conversation.properties
```properties
VehicleConfig.ABSOLUTE_SPEED_LIMIT=30,KILOMETERS,HOURS
VehicleConfig.CarSimulation.NUMBER_OF_WHEELS=4
...
```

As you can see, there is some config which is shared between these files. With
Modular config we can extract the shared elements into a parent file:

knightrider.properties
```properties
VehicleConfig.ABSOLUTE_SPEED_LIMIT=60,KILOMETERS,HOURS
VehicleConfig.CarSimulation.NUMBER_OF_WHEELS=4
...
```

and then declare the extension in the child files, eg:

knightrider_chase.properties
```properties
EXTENDS knightrider

VehicleConfig.ABSOLUTE_SPEED_LIMIT=150,KILOMETERS,HOURS
```

As you can see, the child file may override config from the parent file, but
otherwise inherits the properties of the parent file unchanged.
The `EXTENDS` line should contain the path or resource location of
the parent file, minus the `.properties` suffix. That suffix is
required to be present for the modular config loading to work.
The parent file could itself have an `EXTENDS` line, and as long
as there are no circular references, this can continue as deep as
desired.

## Advanced Usage - Multiple Inheritance

It is also possible to have multiple inheritances.  Say we had the
following files:

knightrider_chase.properties
```properties
VehicleConfig.ABSOLUTE_SPEED_LIMIT=150,KILOMETERS,HOURS
VehicleConfig.RESPECT_TRAFFIC_LIGHTS=FALSE
VehicleConfig.CarSimulation.NUMBER_OF_WHEELS=4
...
```

knightrider_conversation.properties
```properties
VehicleConfig.ABSOLUTE_SPEED_LIMIT=30,KILOMETERS,HOURS
VehicleConfig.RESPECT_TRAFFIC_LIGHTS=TRUE
VehicleConfig.CarSimulation.NUMBER_OF_WHEELS=4
...
```

a_team_chase.properties
```properties
VehicleConfig.ABSOLUTE_SPEED_LIMIT=150,KILOMETERS,HOURS
VehicleConfig.RESPECT_TRAFFIC_LIGHTS=FALSE
VehicleConfig.CarSimulation.NUMBER_OF_WHEELS=3
...
```

We might choose to extract a common knightrider.properties file
as well as a common chase.properties file:

knightrider.properties
```properties
VehicleConfig.ABSOLUTE_SPEED_LIMIT=60,KILOMETERS,HOURS
VehicleConfig.CarSimulation.NUMBER_OF_WHEELS=4
...
```

chase.properties
```properties
VehicleConfig.ABSOLUTE_SPEED_LIMIT=150,KILOMETERS,HOURS
VehicleConfig.RESPECT_TRAFFIC_LIGHTS=FALSE
```

And then we could re-write knightrider_chase.properties as

```properties
EXTENDS knightrider, chase

VehicleConfig.ABSOLUTE_SPEED_LIMIT=150,KILOMETERS,HOURS
```

Note that where both of the parent files define a config value,
it is necessary for the child file to specify an override. There
is no defined system of which parent file takes precedence over
the other. No conflict will be detected if the value is equal in
both parent files.

repository: ocadotechnology/Ocava

gha_language: Java

repo_name: ocadotechnology/Ocava


text:
---
layout: layouts/post.njk
date: 2012-05-14T18:51:00.000Z
slug: tacoconf-anarchism
tumblrid:<PHONE_NUMBER>2
type: text
---

Here are the slides from my TacoConf talk on “Anarchism for Fun and Profit”.

Click on each image to go to the next one, or just scroll down leisurely.  If you prefer, you can get this as a pdf or keynote.

As is so often the case, a lot of great ideas and concepts were left out to make the story seem more straightforward, and to keep it in the time allotted.  I attribute a lot of things to Drucker that were actually developed by a lot of people at the time, and cut out this whole section about Walt Disney, and several other anarchist thinkers.  Max Stirner was just one of several relevant continental philosophers on the topic, etc.

Think of this work as a tease, and let it motivate you to go out and learn more.

I’m here today to talk to you all about Anarchism for fun and profit.  Usually, the way we use these words, what we really mean is:

play and work.  and as I’ll hopefully convince you by the end of this, what we typically think of as play or relaxation is just a brief recovery from what we call “work” which is actually bullshit.

This is what we ought to be doing.

So, I’m gonna give you a little bit of history, mostly to put these ideas into context.  Then, I want to talk about how this applies to work, and some things I’ve observed in the world of software development.

Let’s start at the beginning.

“Anarchy” what does that actually mean?  It’s not just a slogan for punk bands, but it’s also a pretty broad topic.  The definition is right in the word:

“An” meaning “no” or “without”

“Archy” meaning ruler.

So, anarchy is the lack of rulers, hierarchies, and so on.

So, who runs things?

Basically, we all do

Of course, there are degrees of things.  But typically, anarchy implies that associations are voluntary rather than forced, and that each person has control over themselves rather than being controlled by someone else.

A lot of this goes back to a guy named Max Stirner.  Well, actually named Johan Schmidt.  He wrote a book called “The Ego and Its Own”.

One thing that strikes me about Stirner was how similar his lifestyle is to some of ours.  They had this philosophy discussion group back in the mid-19th century in a wine bar in Berlin.

Karl Marx sat in on a few of their sessions, Bruno Bauer, Friedrich Engels, and a bunch of other names you’ve heard of if you got a liberal arts education.

I don’t think they biked around eating tacos, and they probably didn’t write JavaScript in coffee shops, but the similarities to the Oakland tech scene are nonetheless pretty striking.

In this book, he said that the individual is consumed and overwhelmed by ghosts and illusions.  In order to attain Right Action, these ghosts must be left behind.

Here’s a quote that I think sums up what is so interesting about knowledge workers when they’re really working at their best.

So, in other words, he wasn’t writing because it was his job, he was writing because it’s what he does.  He is a writer, and he can’t find out the end of the story unless there’s someone to tell it to.

In this passage, he’s almost half-apologizing for inflicting the truth on society, because he fully expects it will incite revolutions; at the same time saying, “Well, I need to find out the end, so… deal with it.”

More in the modern age,

Bob Black is an American anarchist author, one of the most visible members of the “primativist” movement.    But!  He wrote a really interesting essay, in his spectacularly bombastic style, called The Abolition of Work.  If you aren’t a fan of that style, there’s an essay called In Praise of Idleness by Bertrand Russell, which hits a lot of the same points, but is less confrontational.

He wrote this back in the 80s, and the central thesis of his whole ideology is that we work too much.  Back in the hunter gatherer days, he says, people actually didn’t work nearly as much as they do today.

A lot of the work we do doesn’t actually have to be done.    Our tasks are boring, so we have a hard time focusing on them, so we don’t get much done, and then we feel guilty, and are anxious that our bosses will find out and we’ll be punished somehow.  This anxiety and boredom prevents us from ever achieving that glorious Csikszentmihalyi “flow” state where we have good ideas and feel great.

So, now that we’ve covered the 19th century philosopher anarchists, and the modern day hipster anarchists, I want to switch gears and get a bit more serious here.

How do we make work not sucky?

You really can’t talk about working and management in the modern era without mentioning this guy, Peter Drucker.  It’s really rare to look back at someone from a few decades ago, who was writing about the future, and just go, “Yeah… he was right.  Dude totally called it.”

He was born in Vienna, and grew up sort of just all over Europe in the years after WW1, eventually moving to the US in the 30s.  He was influenced at a early age by Keynes and other economists of that time, but he wrote that he was more interested in the behavior of people rather than the movements of commodities, which is what economists usually focused on.

Viewed now, in light of the science of behavioral economics, it’s clear he was really on to something.  Tversky and Kahneman really went on to define that field, but I don’t have time to talk about them.  His career basically took off with the work he did at GM.

CONCEPT OF THE CORPORATION

GM, the car company.  Drucker was fascinated with the concept of authority, and really believed that making the world a better place would have to be done by the managers running companies, since they held so much power over so many people.

GM hired Drucker to do an extensive analysis of their organization, and from 1943 to 1946, he did just that, resulting in a book called “Concept of the Corporation” which detailed the structure and politics of General Motors, and also delved into its effects on society at large, from the point of view of the political machinations and teams within the organization.

See, up until then, management literature usually focused on a very top-down model.

The idea is that you have a leader, and he has some subordinates.  You tell your subordinates what to do, and they do it, possibly by delegating parts of their tasks to their subordinates, and so on.  So, the question was, how do we draw this tree so that it is the most effective, and how do we deliver orders that will be followed effectively?

It’s a nice simple model, and it’s probably how most people would go about explaining “The Organization” to someone who wasn’t part of it.

But Drucker’s approach was completely different.  He did investigate and explain how GM was organized, and praised them heavily for what was definitely a very scientific approach to developing management techniques and structures.

However, he also showed in this book that this hierarchy is only the tip of the ice berg of what actually happens.  In actuality, those captains (or directors, or whatever) talk to one another, and also talk to the sergeants and privates in other departments, and so on.

He noticed that there was all this cross-department interaction, and that the political hierarchy actually got in the way.  He suggested taking advantage of this, by structuring the company more like this:

A less hierarchical organization structure, where each business unit would be run more like a separate company with its own autonomy, and the ability to freely communicate with other business units.

Well, that was not taken well at GM, and his book was banned at the company.  What’s super interesting is that the Japanese car companies did follow Drucker’s advice and restructure, and proceeded to take advantage of the benefits that Drucker predicted.

This was pretty early in his career.  Again and again, the theme runs through Drucker’s work: Decentralize, push decisions to the edges of the organization, plan on changing direction when the environment changes (he called this “planned abandonment”)

What is most fascinating about Drucker, really his “crystal ball” moment, in 1959, in a book called “the landmarks of tomorrow”, he coined the term “Knowledge Worker”

THE LANDMARKS OF TOMORROW

Drucker predicted that the “Blue collar” worker would soon be a thing of the past.  Increases in mechanization would eventually increase the productivity of a single manual laborer to the point where we just don’t need people doing that.

He also predicted that the manual labor that is still required would be outsourced to countries in the process of developing their infrastructures in the context of all this increased mechanization.

Society would increasingly rely on what he called “Knowledge Work”, or occupations where people think for a living.  Whereas the 20th century is characterized by an increase in efficiency of manual work, the 21st century would be dominated by those who can properly understand and leverage Knowledge Work.

Managing knowledge worker productivity is hard.

The biggest problems is that it’s not even really clear what it is they’re doing.  If you have a manual laborer, and his job is to make widgets, you can just count the widgets at the end of the day, and there you go.

But, somewhat by definition, a knowledge worker isn’t making the same thing over and over again, and the means of production is not a machine, but their brain, so we have to define the task, and often defining the task improperly can change perceptions and inadvertently reduce productivity

Once upon a time, you’d either go to school, or not, and then go to a company like GM or ALCOA, or whatever, that existed for as long as you could remember, and you’d climb a nice little ladder, or stay at the bottom, and after 50 years or so, you’d retire.

Well, with Knowledge Work, because it is unstable by its very nature, since the same knowledge doesn’t need to be created repeatedly, many of us – in fact, most of us – will have careers that long outlast the companies we work for.  Or, if not, if it’s a google or apple, something with some staying power, by the time your career is over, it’ll be a whole different company, making different things in different ways, etc.

In fact, the industrial revolution had already started this wheel in motion.  The information revolution has just accelerated it to the point where we can actually watch it happen in real time.

I’ve worked at a bunch of companies, even technology companies, that still seemed to be stuck in the last century, and didn’t quite “get” what makes knowledge workers work.

I’m sure there are a few people out there who just want to put in their 8 hours like Neitzsche’s Last Man, “earn a living and keep warm”.  The rest of the knowledge workers are working to make their jobs obsolete.

Just as the 20th century was devoted to increasing the productivity of manual laborers to the point where a lot of manual labor simply didn’t need to be done, today’s technology is making a lot of inessential knowledge work go away.  Already, many tasks have been replaced by software.

As Drucker repeated again and again in his work, if you take away the autonomy of knowledge workers, you take away everything that makes them valuable.

Huge fan of this guy.  I think if I had to pick a favorite person I’ve never met but hope I someday do, it’d be Merlin Mann.

You may be familiar with him as the Inbox Zero guy, or 43Folders guy, or @hotdogsladies on twitter, or a bunch of other things.  Talk: Who moved my brain?

Merlin Mann’s history is somewhat interesting, and I think parallels the trajectory of a lot of reasonably successful modern-day knowledge workers.  He did some web stuff, moved to california, worked at a few companies, pretty much hated it, and then ended up finding a niche where he can do what he’s really passionate about.

And that is basically to do podcasts and make dick jokes on the internet, but also he goes and talks to companies about how they’re literally murdering the souls of their employees.

In a lot of ways, Merlin Mann reminds me of Peter Drucker, but instead of spending 3 years writing a book to piss off one company, he goes around and talks at companies that never ever invite him back.

A lot of his work focuses on being a better knowledge worker, but also basically behaving like grownups in organizations.

This is one of those things that’s really easy to think you understand, but really hard to actually get, especially for managers.

Even in a lot of places where they’re are ostensibly trying to empower teams, at some level, priorities are still being handed down to them by people who are under the impression that writing a date on a spreadsheet is some sort of contract with the universe.

What this ultimately comes down to is that there are a lot of little unreasonable assumptions and expectations we place on one another without even realizing it.

Managers can say, “Yeah, check email less, reduce communication overhead, work at a sustainable pace, don’t be interrupt driven”, but then when you try to explain what this means: that your employees will only check their email once per day, meetings should have the minimum number of people in them, and so on, they laugh at you like you’re a crazy person.

In my own life, I’ve been unemployed a few times.  I’ve been poor, though I was lucky enough to be educated and to have a great support network.  I’ve worked for tech companies, and sold vacuum cleaners and other things, I’ve answered phones.  Not having a job when I needed money was probably the most stressful time in my life.

But, for a few months in 2010, I didn’t have a job, but I didn’t actually need one.  I’d worked at Yahoo for 4 years, and got sort of sick of it.  So, I planned out how long my money would last, and decided to see what would happen if I just didn’t have an employer for a while.

I highly recommend knowledge workers do this, at least every few years.  I didn’t even realize how burnt out I’d become, and those few months of idleness, well,

it just doesn’t really make much sense to call it “idleness”, since it was one of the most productive times of my life.

Why be productive when you don’t have a job?

Of course, I don’t want to make it seem like jobs are necessarily bad things.

A lot of times, a company gives you access and opportunity to do the things you’re passionate about, and that’s when it’s awesome.

But what really struck me about that time was how I felt so much more motivated to work on node than I ever had felt on any project before.  And as I looked around the node community, it seemed really interesting to me in those early days that everyone was working their asses off, and loving it

I don’t know if who first coined this term, but I’ve sometimes referred to the Node.js ecosystem, and particularly the npm registry, as a “mostly anarchic dictatorship”.

That is, there’s definitely leadership, but the leader’s role is shrunken down to almost nothing.  Because we built a decent module system, and node provided APIs that were easy to extend, little fiefdoms and satellite projects spun up.

So, it’s maybe not “anarchy” in the purest sense, but it’s about as close as we can get.  Anyone has the opportunity to leave and do their own thing, and the leader’s role is mostly just to help everyone out, not to tell them what to do.

The awesome thing about working on an open source project like Node is that it is an anarchy with one dictator who is really answerable to the rest of the community.  The leader doesn’t have any control over a person’s income, so if you want a person to work harder, well… you have to make it enticing.

This means that we have to plan for occasional outages, or for people losing interest randomly and disappearing.

The payoff, though, is that people actually have a sense of ownership of what they do, because they’re endowed with a sense of agency, and that attracts more people to come help, and when they’re done with whatever it was that was distracting them, they tend to come back.

Dan Pink has a great talk on this, where he goes through lots and lots of evidence and reproduced studies.  The more people feel like they’re in control of what they do, the more than that they are connected via social ties, the more respect they are shown, the better and more creatively they can perform.

It’s not about how many hours you spend in an office.  It’s about what you get done, and how good it is.

A lot of times, I think teams tend to forget what their mission is.  Or, worse, they may not have ever had one.

It’s definitely helpful sometimes to have meetings or estimate when things will be done.    But, the verb “lead” really implies a much more active role, and an assumption that we are actually going somewhere.  “Managing” means we’re just kinda keeping everything in place.

The person who is ostensibly in charge of a team of knowledge workers needs to be a person who takes on a lot of group-helping tasks, but also is intimately involved in the project.  Most of their job has to be to listen, not to tell.  Because knowledge work happens best when it’s fun, and > fun cannot be forced

fun cannot be forced.

People work better when they’re having fun.  So, this means that you have to let them work on things they care about, help them find good things to work on, and mostly stay out of their way.

So, I’m way over my time limit here I think, but if anyone wants to talk about any of this stuff, I’ll be around.  Thanks!

gha_language: JavaScript

gha_license_id: NOASSERTION


text:
# Dunner [![Release](https://img.shields.io/github/release/leopardslab/dunner.svg)](https://img.shields.io/github/release/leopardslab/dunner.svg)

[![Codacy Badge](https://api.codacy.com/project/badge/Grade/b2275e331d2745dc9527d45efbbf2da2)](https://app.codacy.com/app/Leopardslab/dunner?utm_source=github.com&utm_medium=referral&utm_content=leopardslab/dunner&utm_campaign=Badge_Grade_Dashboard)
[![Codecov branch](https://img.shields.io/codecov/c/github/leopardslab/dunner/master.svg)](https://codecov.io/gh/leopardslab/dunner)
[![Build Status](https://travis-ci.org/leopardslab/Dunner.svg?branch=master)](https://travis-ci.org/leopardslab/Dunner)
[![GoDoc](https://godoc.org/github.com/leopardslab/dunner?status.svg)](https://godoc.org/github.com/leopardslab/dunner)
[![GoReport](https://goreportcard.com/badge/github.com/leopardslab/dunner)](https://goreportcard.com/report/github.com/leopardslab/dunner)
[![Join the chat at https://gitter.im/LeaopardLabs/Dunner](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/LeaopardLabs/Dunner)

> The Docker Task Runner

Dunner is a task runner tool based on Docker, simple and flexible. You can define tasks and configure the environment in your `.dunner.yaml` file and then run as `dunner do <taskname>`.

Example `.dunner.yaml`:

```yaml
envs:
  - AWS_ACCESS_KEY_ID=`$AWS_KEY`
  - AWS_SECRET_ACCESS_KEY=`$AWS_SECRET`
  - AWS_DEFAULT_REGION=us-east1
tasks:
  deploy:
    steps:
      - image: 'emeraldsquad/sonar-scanner'
        commands:
          - ['sonar', 'scan']
      - image: 'golang'
        commands:
          - ['go', 'install']
      - image: 'mesosphere/aws-cli'
        commands:
          - ['aws', 'elasticbeanstalk update-application --application-name myapp']
      - follow: 'status' #This refers to another task and can pass args too
        args: 'prod'
  status:
    steps:
      - image: 'mesosphere/aws-cli'
        commands:
          # This uses args passed to the task, `$1` means first arg
          - ['aws', 'elasticbeanstalk describe-events --environment-name $1']
```

Running `dunner do deploy` from command-line executes `deploy` task inside a Docker container. It creates a Docker container using specified image, executes given commands and shows results, all with just simple configuration!

## Features

* [Easy Configuration](https://github.com/leopardslab/dunner/wiki/User-Guide#how-to-write-a-dunner-file) to run tasks inside container
* [Multiple commands](https://github.com/leopardslab/dunner/wiki/User-Guide#multiple-commands)
* [Mount external directories](https://github.com/leopardslab/dunner/wiki/User-Guide#mounting-external-directories)
* [Environment Variables](https://github.com/leopardslab/dunner/wiki/User-Guide#exporting-environment-variables)
* [Pass arguments through CLI](https://github.com/leopardslab/dunner/wiki/User-Guide#passing-arguments-through-cli)
* [Add dependent task](https://github.com/leopardslab/dunner/wiki/User-Guide#use-a-task-as-a-step-for-another-task)
* [Asynchronous mode](https://github.com/leopardslab/dunner/wiki/User-Guide#asynchronous-mode)
* [Dry Run](https://github.com/leopardslab/dunner/wiki/User-Guide#dry-run)

and [more](https://github.com/leopardslab/dunner/wiki/User-Guide)...

# Getting Started

Read more about [Why Dunner](https://github.com/leopardslab/dunner/wiki/Introduction-to-Dunner) and refer our guides for [installation](https://github.com/leopardslab/Dunner/wiki/Installation-Guide) and [usage](https://github.com/leopardslab/dunner/wiki/User-Guide).

| [**User Documentation**](https://github.com/leopardslab/dunner/wiki/User-Guide)     | [**Installation Guide**](https://github.com/leopardslab/dunner/wiki/Installation-Guide)     | [**Dunner Examples**](https://github.com/leopardslab/dunner-cookbook)           | [**Contributing**](https://github.com/leopardslab/dunner/wiki/Developer-Guide)           | [**Dunner GoCD Plugin**](https://github.com/leopardslab/dunner-gocd-plugin#dunner-gocd-plugin)           |
|:-------------------------------------:|:-------------------------------:|:-----------------------------------:|:---------------------------------------------:| :--------------------------------------:|
| Learn more about using Dunner | Getting started with Dunner | Dunner Cookbook Recipes | How can you contribute to Dunner? | Have a look at Dunner [GoCD](https://www.gocd.org/) Plugin |

## Development Plan

Have a look at [Dunner Milestones](https://github.com/leopardslab/dunner/milestones) for our future plans.

## Contributing

We'd love your help to fix bugs and add features. The maintainers actively manage the issues list, and try to highlight issues suitable for newcomers. The project follows the typical GitHub pull request model. Before starting any work, please either comment on an existing issue, or file a new one. Refer our [Developer Guide](https://github.com/leopardslab/dunner/wiki/Developer-Guide) for more.

repository: nimsandu/dunner

repo_name: nimsandu/dunner


text:
Title: Chromosome Segmentation
Tagline: Develop a specialized visual segmentation model to help cytogeneticists conduct research.
Date: October 2016
Category: Applied Research
Mailing list: https://groups.google.com/d/forum/aion-visual-segmentation-of-chromosomal-preparations
Contact: Jean-Patrick Pommier - Univerité Pierre et Marie Curie

## Problem description

In cytogenetics, experiments typically starts from chromosomal preparations fixed on glass slides. Occasionally a chromosome can fall on another one, yielding overlapping chromosomes in the image. Before computers and images processing with photography, chromosomes were cut from a paper picture and then classified (at least two paper pictures were required when chromosomes are overlapping). More recently, automatic segmentation methods were developped to overcome this problem. Most of the time these methods rely on a geometric analysis of the chromosome contour and require some human intervention when partial overlap occurs. Modern deep learning techniques have the potential to provide a more reliable, fully-automated solution.

## Why this problem matters

A fast and fully-automated segmentation solution can allow to scale certain experiments to very large number of chromosomes, which was not possible before. E.g. quantitative analysis of hybridization fluorescent signal on metaphasic chromosomes in the case of telomere length analysis.

## Datasets

- [overlapping-chromosomes](https://www.kaggle.com/jeanpat/overlapping-chromosomes/downloads/overlapping-chromosomes.zip) - note that following this link triggers a download.

## References

- [A Geometric Approach To Fully Automatic Chromosome Segmentation](https://arxiv.org/abs/1112.4164)
- [Automated Discrimination of Dicentric and Monocentric Chromosomes by Machine Learning-based Image Processing](http://biorxiv.org/content/biorxiv/early/2016/01/19/037309.full.pdf)
- [An Efficient Segmentation Method for Overlapping Chromosome Images](http://research.ijcaonline.org/volume95/number1/pxc3894861.pdf)
- [A Review of Cytogenetics and its Automation](http://www.scialert.net/qredirect.php?doi=jms.2007.1.18&linkid=pdf)


text:
---
title: cpupower usage guide
date: 20181101
tags: cpupower,scaling,governor,frecuency,power,battery,management
---

# cpupower usage guide

## Change the governor

`cpupower frequency-set -g [governor]`

[archlinux-wiki](https://wiki.archlinux.org/index.php/CPU_frequency_scaling#Scaling_governors)


text:
# Nautilus Desktop Entry creator script
Simple script for creating desktop entry by click

# Install
Install dependencies: ```sudo apt install icoutils```

Put file "```Create Desktop entry```" into "```~/.local/share/nautilus/scripts```"

Restart Nautilus or relog in:

```nautilus -q && nautilus &```

# Showcase
![Video](https://github.com/WinPooh32/NautilusDesktopEntry/raw/master/video.gif)


text:
---
title: Tarbell
repo: tarbell-project/tarbell
homepage: http://tarbell.io
language:
  - Python
license:
  - BSD-3-Clause
templates:
  - Jinja
description: Simple static sites for storytellers.
---

**Tarbell** makes use of familiar, flexible tools to take the magic (and frustration) out of publishing to the web. Google spreadsheets handle content management, so changes to your pages are easy to make without touching a line of code. Step-by-step prompts help you set up and configure your project, so that publishing it is a breeze.

Read more about [how to install Tarbell](http://tarbell.readthedocs.org/en/latest/install.html), or follow along with our [tutorial](http://tarbell.readthedocs.org/en/latest/tutorial.html). You can also [follow updates on Twitter](https://twitter.com/tarbellproject).

Tarbell is named after celebrated journalist Ida Tarbell, who was all about making information more accessible.


text:
# php7-optional
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Tests](https://github.com/iFixit/php7-optional/actions/workflows/test.yaml/badge.svg?branch=master)](https://github.com/iFixit/php7-optional/actions/workflows/test.yaml)
[![Stable Version](https://img.shields.io/packagist/v/ifixit/php7-optional.svg)](https://packagist.org/packages/ifixit/php7-optional)
[![Downloads](https://img.shields.io/packagist/dm/ifixit/php7-optional.svg)](https://packagist.org/packages/ifixit/php7-optional)
[![codecov](https://codecov.io/gh/iFixit/php7-optional/branch/master/graph/badge.svg)](https://codecov.io/gh/iFixit/php7-optional)
[![psalm](https://shepherd.dev/github/ifixit/php7-optional/level.svg)](https://shepherd.dev/github/ifixit/php7-optional)
[![psalm](https://shepherd.dev/github/ifixit/php7-optional/coverage.svg)](https://shepherd.dev/github/ifixit/php7-optional)
[![Pull Requests](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?longCache=true)](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?longCache=true)

## Installation

```sh
composer require ifixit/php7-optional
```

## Usage

There are 3 main classes:

* [Optional\Option](https://php7-optional.surge.sh/Optional/Option.html)
   * Conceptually: Some or None. This is a box that optionally holds a value. Use this to replace null.
* [Optional\Either](https://php7-optional.surge.sh/Optional/Either.html)
   * Conceptually: Left or Right. This is a box that is bi-state. Can be Left, or Right. Not Both, not none. You can apply the same transformations to the left side as you can to the right.
* [Optional\Result](https://php7-optional.surge.sh/Optional/Result.html)
   * Conceptually: Okay or Error. This is a box that is bi-state, but leans towards okay state. The error state is limited as we want to make this object easy to deal with mapping or dump error.
   * All callables have `Throwable` auto wrapped and thrown at the end of the chain.
* [Optional\UnsafeResult](https://php7-optional.surge.sh/Optional/UnsafeResult.html)
   * Conceptually: Okay or Error. This is a box that is bi-state, but leans towards okay state. The error state is limited as we want to make this object easy to deal with mapping or dump error.
   * All callables do not have `Throwable` auto wrapped. Thus, an Exception will be thrown immediately.

## [Read the full docs](https://php7-optional.surge.sh/)

## Using Option

To use Optional, simply import the following namespace:

```php
use Optional\Option;
```

## Creating optional values

There are examples under `examples`.

Here is one of them which will show how fluently you can describe the chnage you want to apply.

```php
use Optional\Result;

class Curl {
   public static function request(string $url): array {
      return [
         'code' => 200,
         'url' => $url,
         'data' =>
            '{
               "environment_config": {
                 "app": {
                   "name": "Sample App",
                   "url": "http://<IP_ADDRESS>:8080/app/"
                 },
                 "database": {
                   "name": "mysql database",
                   "host": "<IP_ADDRESS>",
                   "port": 3128,
                   "username": "root",
                   "password": "toor"
                 },
                 "rest_api": "http://<IP_ADDRESS>:8080/v2/api/"
               }
             }'
      ];
   }
}

$responseToResult = function (array $response): Result {
   $wasGood = $response['code'] == 200;

   if ($wasGood) {
      return SimpleResult::okay($response);
   } else {
      $url = $response['url'];
      $code = $response['code'];
      return SimpleResult::error("The request to $url failed with code $code!");
   }
};

$response = Curl::request('http:://www.github.com');

$result = $responseToResult($response);

$dbConnectionStr = $result
   ->map(function ($result) {
      return json_decode($result['data'], true);
   })
   ->notFalsy("Json failed to decode!")
   ->map(function(array $json) {
      $dbData = $json['environment_config']['database'];

      $host = $dbData['host'];
      $port = $dbData['port'];
      $username = $dbData['username'];
      $password = $dbData['password'];

      return "Server=$host;Port=$port;Uid=$username;Pwd=$password;";
   })
   ->dataOrThrow();

echo "Connection str: $dbConnectionStr \n";

$dbConnectionResult = $result
   ->map(function ($result) {
      return false;
   })
   ->notFalsy("Json failed to decode!")
   ->map(function(array $json) {
      $dbData = $json['environment_config']['database'];

      $host = $dbData['host'];
      $port = $dbData['port'];
      $username = $dbData['username'];
      $password = $dbData['password'];

      return "Server=$host;Port=$port;Uid=$username;Pwd=$password;";
   });

   try {
      $dbConnectionResult->dataOrThrow();
   } catch (Throwable $ex) {
      // Don't want to kill the example
      echo "Example of a wrapped exception: {$ex->getMessage()}\n";
   }

   $defaultValue = $dbConnectionResult
   ->orSetDataTo('Server=myServerAddress;Port=1234;Database=myDataBase;Uid=myUsername;Pwd=myPassword;')
   ->dataOrThrow();

   echo "Example of setting to a default: $defaultValue\n";
```

## Using Either

To use Either, simply import the following namespace:

```php
use Optional\Either;
```

## Using Result

To use Result, simply import the following namespace:

```php
use Optional\Result;
```

### Result Methods

#### Creation (Boxing)
---
- static okay($data): Result
- static error(Throwable $errorData): Result
- static okayWhen($data, Throwable $errorValue, callable $filterFunc): Result
- static errorWhen($data, Throwable $errorValue, callable $filterFunc): Result
- static okayNotNull($data, Throwable $errorValue): Result
- static fromArray(array $array, $key, Throwable $rightValue = null): Result

### Flipping
---
- toError($errorValue): Result
- toOkay($dataValue): Result

### Unboxing
---
- dataOrThrow()

### State
---
- isOkay(): bool
- isError(): bool
- contains($value): bool
- errorContains($value): bool
- exists(callable $existsFunc): bool

### Transformation
---
- orSetDataTo($data): Result
- orCreateResultWithData(callable $alternativeFactory): Result
- okayOr(self $alternativeResult): Result
- createIfError(callable $alternativeResultFactory): Result
- map(callable $mapFunc): Result
- mapError(callable $mapFunc): Result
- andThen(callable $mapFunc): Result
- flatMap(callable $mapFunc): Result
- toErrorIf(callable $filterFunc, Throwable $errorValue): Result
- toOkayIf(callable $filterFunc, $data): Result
- notNull(Throwable $errorValue): Result
- notFalsy(Throwable $errorValue): Result

### Side Effect
- run(callable $dataFunc, callable $errorFunc)
- runOnOkay(callable $dataFunc): void
- runOnError(callable $errorFunc): void

# Licence
 MIT

# Special Thanks
Heavily inspired by https://github.com/nlkl/Optional. In fact this is essentially a port of this library.


text:
# UK PM Johnson's Conservatives have 7-point lead over Labour

Published at: **2019-11-04T16:51:09+00:00**

Author: ****

Original: [Aljazeera](https://www.aljazeera.com/news/2019/11/uk-pm-johnson-conservatives-7-point-lead-labour-191104155857989.html)

British Prime Minister Boris Johnson's Conservatives have a seven percentage-point lead over the opposition Labour Party ahead of a December 12 election, according to an ICM poll published by Reuters on Monday.
ICM's first poll of the election campaign put the Conservatives on 38 percent and Labour on 31 percent.
The pro-European Union Liberal Democrats had the support of 15 percent of those surveyed, while the Brexit Party was on nine percent.
The poll of 2,047 people, carried out online between November 1 and 4, shows a narrower gap than recent surveys from other pollsters, which have put the Conservatives between 8 and 17 percentage points ahead of Labour.
ICM said the survey showed the two main parties losing a similar proportion of voters over Brexit.
It said 11 percent of those who voted Conservative at the last election in 2017 were now planning to vote for the Brexit Party, while 12 percent of those who backed Labour in 2017 intended to vote for the Liberal Democrats.
More than two-thirds of those who voted "Remain" in the Brexit referendum in 2016 and for the Conservatives in 2017 intended to stick with Johnson's Conservatives, ICM said.

license: Unlicense

repository: dsadlollioygjmzvcxv/tdc-exported

repo_name: dsadlollioygjmzvcxv/tdc-exported


text:
# RESTA SCRIPTS

### Environment

To run the tests you will need at least one environment file. The environment file name should be in the following format:  `env-{name}.json` where `name` is the name of the environment. For example, `env-uat.json` is the file for the **uat** environment. The environment file has the following structure:

```json
{
	"title": "Environment title",
	"values": {
		"key1": "value one",
		"key2": "value two",

		"keyN": "value N"
	}
}
```

You can create as many environments as you like. The values property contains environment-specific values you can use in your scripts and data. Here is an example of the environment file:

```json
{
  "title": "Cloud QA",
  "values": {
    "url": "http://dummy.restapiexample.com/api",
    "key": "75486571884"
  }
}
```

#### Using Variables

Before RESTA executes a script, it creates the context – an in-memory dictionary of values that all script tasks can use. Before the first task starts, the context is populated by the variables loaded from the environment file. Tasks can use the **read** section to update variables in the context.

RESTA uses mustaches syntax for variables. To use the context value in a string, enter the variable name in the double curly brackets. Before executing the task, RESTA will replace variables with actual values. For example:

```json
{
   "url": "{{baseurl}}/api/auth"
}
```

If the context has a variable called **baseurl** and its value is `http://localhost:8080`, the RESTA execute the task that looks like this:

```json
{
   "url": "http://localhost:8080/api/auth"
}
```

Since version 1.1.12 RESTA also supports the following dynamic variables:

| Variable name | Description                                         | Example                              |
| ------------- | --------------------------------------------------- | ------------------------------------ |
| $guid         | Generates a GUID (Globally Unique Identifier) in v4 | 15aacbb1-1615-47d8-b001-e5411a044761 |
| $timestamp    | Returns the current timestamp                       |<PHONE_NUMBER>                           |
| $randomInt    | Generates random integer between 0 and 1000         | 764                                  |

### Schemas

File name `shema-{name}.json`. For example, `schema-object.json` is the schema file you are referring to as “object”.

```json
{
  "description": "Any Object",
  "type": "object"
}
```

You can create as many schema files as you like. You do not need to create file for default schemas `object` and `array`.

### Scripts

RESTA script is a JSON file that contains one or several tasks (API calls). The script file name must be in the following format: `script-{name}.json`. For example, the `script-smoke-test.json` file contains the script with the ID “smoke-test”. The script file has the following structure:

```json
{
	"id": "{script-id}",
	"title": "{script-title}",
	"shared": {
    "timeout": {timeout},
		"header": {
			"Accept": "applicstion/json"
		}
	},

	"tasks": [
		{ ...task 1 },
		{ ...task 2 },
    ...
		{ ...task N }
	]
}
```

The **shared** section contains features that will apply to every task. For example, all key-value pairs specified in the shared header will be added to the HTTP header of every API call.

The **tasks** array contains the list of API calls. The script is an environment-agnostic flow that executes all tasks sequentially. Use script as a functional test of a particular scenario or a use case. You will be able to run multiple scripts together as defined in the runbook (see below).

#### Tasks

Every task in the **tasks** array represents a single REST API call. Here is the structure of the task object:

```json
{
	"id": "{task-id}",
	"disabled": true|false,
	"title": "{task-title}",
	"method": "GET|POST|PUT|DELETE",
	"url": "{full-path-of-the-api}",
  "timeout": {timeout},
  "wait": {pause},
  "header": {},
  "body": "",
	...segments...
}
```

Here are the primary properties of the task object:

* The `id` property is a unique ID of the task in the script.
* The `title` property is a text that is displayed on the screen and in the test report.
* The `disabled` property is a flag that can be used to skip some tasks during script execution.
* The `method` property indicates the HTTP method of the request. RESTA supports [GET](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET), [POST](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST), [PUT](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT), [DELETE](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/DELETE), [HEAD](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/HEAD), [OPTIONS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS), [PATCH](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH), MERGE, and COPY .
* The `url` property contains the URL of the API request.
* The `timeout` property specify the call time-out in milliseconds. The default time-out is 5 seconds.
* The `wait` property sets a delay in milliseconds. If more than zero, the script will pause before executing this task. Maximum value is 60 seconds.
* The `header` property is optional. It contains key-value pairs that RESTA will add to the HTTP header of the API request.
* The `body` property is used for the POST and PUT methods. It contains the name of the file in the data directory. RESTA will send the content of this file in the HTTP body of the API request.
* The `content` property is an alternative to the property `body`. You can use it to provide the request body. In that case, you do not have to create a separate file. The `content` support only JSON requests.
* A task may also include one of the following segments: *assert*, *x509*, and *read*. You will find more details below.

Here is an example of the script task:

```json
{
	"id": "test-auth",
	"disabled": false,
	"title": "API Authentication using token",
	"method": "POST",
	"url": "{{baseurl}}/api/authenticate",
	"body": "user-id",
	"header": {
	  "Authorization": "Bearer {{authToken}}"
	},
	"assert": {
		"response": 201,
		"type": "application/json",
		"schema": "object"
	}
}
```

Notice how environment variables are used here to represent values of the script context.

#### Assert segment

The **assert** segment contains a list of tests used to determine whether the call failed or ran as expected. The segment has the following structure:

```json
{
	"assert": {
		"response": {code},
    "responses": [ {code1}, {code2}],
		"type": "{mime-type}",
    "schema": "{schema-name}"
	}
}
```

All fields of the assert object are optional.

- The **response** field specifies the expected HTTP response code. Alternatively, you can provide an array of acceptable codes. For that, you have to use field **responses**.

- The **type** field specifies the expected response MIME type.

- The **schema** field contains the name of the JSON schema. If this field is provided, then the response must match the JSON schema found in the `schema-{name}.json` file.

```json
{
	"assert": {
		"responses": [200, 201],
		"type": "application/json",
    "schema": "object"
	}
}
```

In this example, the API call will succeed if it returns either HTTP code 200 or 201.

#### x.509 certificate segment

Use this section only if the server requires the client to provide an x.509 certificate. The x509 section has the following structure:

```json
{
	"x509": {
		"file": "{file-name.pfx}",
		"password": "{pfx-password}"
	},
}
```

The **file** property contains the name of the certificate file. RESTA accepts files in PFX format only. Use the **password** property to enter the password of the certificate. Here is an example of the x509 section:

```json
{
	"x509": {
		"file": "client-qa.pfx",
		"password": "xyz123"
	},
}
```

The client-qa.pfx file must be in the same folder as the script file.

#### Read values segment

This segment allows you to read the API call's output so you can use it in other calls as parameters. The **read** section has the following structure:

```json
{
  "read": [
    {
	    "locate": "{path-to-find}",
		  "target": "{var-to-update}"
	  },
	  { ... },
	  { ... }
  ]
}
```

Every object in the array has two fields.

- The **locate**: JSONPath query to locate the particular value in the API response. Find out more about JSONPath [here](http://goessner.net/articles/JsonPath/).

- The **target**: name of the variable to assign this value to.

All variables are stored in the script context, along with variables loaded from the environment file. Here is an example of the read section:

```json
{
  "read": [
    {
	    "locate": "token",
		  "target": "authToken"
	  }
  ]
}
```

The script will find the property **token** in the response and assign its value to the context variable **authToken**.

### Runbooks

Runbook is a JSON file that contains instructions for executing multiple API scripts in the selected environment. The runbook file has the following structure:

```json
{
	"title": "{runbook-title}",
	"environment": "{environment-name}",
	"scripts": [
		"{script-name}", "{script-name}", "{script-name}"
	]
}
```

Here is an example of the RESTA runbook:

```json
{
	"title": "System Health Check",
	"environment": "uat",
	"scripts": [
		"ping-api",
    "read-summary"
	]
}
```

You can create multiple runbook files to support your testing needs.

### Test Results

RESTA saves the result of every test call in the API execution report. The report file name has the following structure: `api-{script}-{task}.json` where **script** is the script ID and **task** is the task ID. The report file has the following structure:

```json
{
  "scriptid": "{script-id}",
  "taskid": "{task-id}",
  "url": "{Method} {url}",
  "time": "{time-stamp}",
  "duration": {duration-ms},
  "htmlcode": {response-code},
  "type": "{response-mime}",
  "warnings": [],
  "response": { },
  "responseHeader": { },
  "raw": {raw-output},
  "input": { }
}
```

RESTA executes every script in the runbook one by one. For every script the it executes a sequence of tasks (API calls). If the task test execution succeeded, then RESTA will delete the report file. If you want to keep report files for successful calls, use `-keep` parameter in the command line.

The API test report contains the following fields:

- **scriptid**: ID of the script
- **taskid**: ID of the task inside the script
- **URL**: HTTP command in the following format: `{method} {url}`
- **time**: Timestamp when the test was executed (local time)
- **input**: the body of the request
- **duration**: Duration of the call in milliseconds
- **htmlcode**: The response HTML code
- **type**: The MIME type of the response
- **response**: The body of the response (JSON format)
- **responseHeader**: The HTTP response header variables (requires command-line option `-rh` )
- **raw**: The body of the response in raw format. This field is provided only if the body cannot be converted to JSON.
- **warnings**: List of messages generated by failed assertions. The API call is considered successful if the warning list is empty.

Here is an example of the RESTA test report file:

```json
{
  "scriptid": "px-cspapi",
  "taskid": "auth-login-cspa",
  "url": "POST https://test-api.qa.service.com/login",
  "time": "09/21/2021 05:59:27",
  "duration": 457,
  "htmlcode": 400,
  "type": "application/json",
  "warnings": [
    "Invalid response code: 400. Expected 200"
  ],
  "response": {
    "message": "Missing required parameter: username"
  },
  "input": {
    "email"<EMAIL_ADDRESS>    "password": "bigsecret"
  }
}
```

In addition to the execution reports, RESTA will save the updated environment to the output folder. The file `env-{name}.json` will contain all key-value pairs including the ones obtained by scripts using the `read` section.

---

repository: skch/RESTA

gha_language: C#

repo_name: skch/RESTA


text:
---
title: "Connect MVISION Cloud to AWS"
chapter: false
weight: 300
---

MVISION Cloud utilizes AWS' comprehensive set of APIs to provide security for IaaS services such as EC2 and S3.  Later sections of this workshop will provide details on the details of the security provided, the following describes the functionality of MVISION Cloud for AWS at a high level:

![MVISION Cloud](/images/mfe/mvcforAWS.png?classes=border,shadow)

In order to provide this security, your MVISION Cloud tenant will need access to various components of your AWS environment.  Let's get started on creating a role.

#### Determine your MVISION Cloud AWS Account ID

### MVISION Cloud URL ###

https://www.myshn.net

1.  From the MVISION Cloud dashboard, click the configuration wheel and click **service management**.

  ![Enter Service Management](/images/mfe/clickservicemanagement.png?classes=border,shadow)

2.  Click **Add Service Instance**, select AWS, and provide a name for the instance when promted ("AWS" will work just fine)

3.  On the **Account Settings** screen make a note of your **MVISION Cloud AWS Account ID** and **External ID** then select the checkboxes shown below then click **next**.

  ![Enter Service Management](/images/mfe/mvcsetup01.png?classes=border,shadow)

4.  Acknowlege the pre-requisites and click **next**

5.  You will be presented with a page to enter you AWS Role ARNs.  Leave this browser tab where it is and we will come back to it later.

#### Create an AWS Role for MVISION Cloud

1.  Login to your AWS account and select **IAM** from the services menu.

2.  From IAM, navigate to Roles and search for "mcafee". Select "McAfeeServiceRole".

  ![MVISION Cloud for AWS Summary](/images/mfe/mvcsetup02.png?classes=border,shadow)

  On the Summary page for the Role, select the "Trust Relationships" tab and then click "Edit trust relationship".

![MVISION Cloud for AWS Summary](/images/mfe/mvcsetup03.png?classes=border,shadow)

Within the JSON formatted permissions, modify the Account ID and External ID as shown in the screenshot below. The Account ID and External ID are available on the MVISION Cloud page.

Once finished, click Update Trust Policy button.

![MVISION Cloud for AWS Summary](/images/mfe/mvcsetup04.png?classes=border,shadow)

Once back at the Summary page for the Role, copy the "Role ARN" value. You will use this value momentarily within MVISION Cloud.

![MVISION Cloud for AWS Summary](/images/mfe/mvcsetup05.png?classes=border,shadow)

#### Configure MVISION Cloud to use the new AWS Role

1.  Return to the MVISION Cloud configuration screen.

2.  Enter the new Role ARN you recorded in the previous step and provide a friendly name such as the one shown below, click **add** and then click **Authenticate Accounts**
![MVISION Cloud for AWS Summary](/images/mfe/mvcsetup06.png?classes=border,shadow)

![MVISION Cloud for AWS Summary](/images/mfe/mvcsetup07.png?classes=border,shadow)

Please note, you will get a warning Regarding Non Critical Errors as shown below. It is safe to "Continue with Error".

![MVISION Cloud for AWS Summary](/images/mfe/mvcsetup08.png?classes=border,shadow)

7.  Review all of the information and click **Save**

![MVISION Cloud for AWS Summary](/images/mfe/mvcsetup09.png?classes=border,shadow)

#### Congratulations MVISION Cloud is now configured and ready for use with AWS!

repository: lmarecha-creator/mcafeecloudguru

repo_name: lmarecha-creator/mcafeecloudguru


text:
# Change Log

All notable changes to the ModalEdit extension will be documented in this file.

## Version 1.0

- Initial release

## Version 1.1

- Added `selectTillMatch` argument to `modalEdit.search` command.
- Editor does not automatically revert back to normal mode when changing window.

## Version 1.2

- Added `startInNormalMode` setting, resolving issue
  [#1](https://github.com/johtela/vscode-modaledit/issues/1)

## Version 1.3

- Incremental search now returns to insert mode, if it was invoked from there
  [#4](https://github.com/johtela/vscode-modaledit/issues/4)
- Added new command `modaledit.typeNormalKeys` which can be used to "call"
  key bindings. Also fixes issue
  [#3](https://github.com/johtela/vscode-modaledit/issues/3)
- Added new argument `typeAfterAccept` to `modaledit.search` command. This
  invokes normal mode key bindings (using `modaledit.typeNormalKeys`) after
  successful search. The argument can be used to enter insert mode, or clear
  selection after search, for example.

## Version 1.4

- Fixed few issues with `modaledit.search` command.
- You can use `__selection` variable in JS expressions to access currently
  selected text.

## Version 1.5

Update that was sparked by issue [#6](https://github.com/johtela/vscode-modaledit/issues/6).
Contains multiple new features:

- `repeat` attribute added to commands with parameters.
- Keymaps can contain [key ranges](https://johtela.github.io/vscode-modaledit/docs/README.html#key-ranges).
- Support for [recursive keymaps](https://johtela.github.io/vscode-modaledit/docs/README.html#defining-recursive-keymaps).
- New `__keySequence` variable added to JS expressions. Contains the key
  sequence that was used to invoke a command.
- New property `help` added to keymaps. The help string is shown in the status
  bar when the associated keymap is active.
- Added ModalEdit log to [output window](https://johtela.github.io/vscode-modaledit/docs/README.html#debugging-keybindings).
- Semi-large refactoring of type definitions in the [actions module](https://johtela.github.io/vscode-modaledit/docs/src/actions.html).

## Version 1.6

- [New command `modaledit.selectBetween`](https://johtela.github.io/vscode-modaledit/docs/README.html#selecting-text-between-delimiters)
  selects text between two delimiter strings. Especially useful when combined
  with the key ranges and recursive keymaps introduced in version 1.5.
- Added a shorter alias `__keys` to the `__keySequence` variable available in
  JS expressions.

## Version 1.7

Two "repeat" related bigger improvements:

- New [`modaledit.repeatLastChange` command](https://johtela.github.io/vscode-modaledit/docs/README.html#repeat-last-change)
  emulates Vim's dot `.` command quite faithfully.
- The `repeat` property used in context with
  [commands taking arguments](https://johtela.github.io/vscode-modaledit/docs/README.html#commands-with-arguments) can now also contain a JS expression that
  returns a boolean value. In this case, the value is used as a condition that
  tells if the command should be repeated. The command is repeated as long as
  the expression returns a truthy value.

And some minor changes:

- New variable `__rkeys` available for use in JS expressions. It contains the
  keys pressed to invoke a command in reverse order. This is handy if you need
  to access the last keys in the sequence. They are conveniently the first ones
  in `__rkeys`.
- Removed unneeded images from the extension package. The package is now 3 MBs
  smaller.

## Version 2.0

Major release containing lot of new features and improvements.

### Preset keybindings

It is possible now to import keybindings through the `modaledit.importPresets`
command. [Vim presets](preset/vim.html) are included in the extension
([#7](https://github.com/johtela/vscode-modaledit/issues/7)). The presets can be
also defined as JavaScript ([#9](https://github.com/johtela/vscode-modaledit/issues/9)).
They are evaluated or "compiled" to JSON when import is run.

### Improvements to Search

Search command has several new features:

- Multicursor search ([#5](https://github.com/johtela/vscode-modaledit/issues/5),
  [#12](https://github.com/johtela/vscode-modaledit/pull/12)) is now working.

- There are four new parameters: `typeBeforeNextMatch`, `typeAfterNextMatch`,
  `typeBeforePreviousMatch`, and `typeAfterPreviousMatch`. These can be used to
  run key commands after `modaledit.nextMatch` and `modaledit.previousMathch`
  commands. The need for these parameters arose when implementing Vim's `t` and
  `f` key commands. These commands look for specified character and place the
  cursor either on it or before it. Without the new parameters, it would not
  be possible to emulate Vim's behavior using `modaledit.search`. This is
  because by default, it selects the search string and search always starts from
  the current cursor position. To make jumping to next and previous character
  possible, we need to adjust the cursor position before and after the commands.

- New parameter `wrapAround` causes the search to jump the beginning/end of
  the file if it hits bottom/top. This closes issue [#8](https://github.com/johtela/vscode-modaledit/issues/8)

- The implementation of `modaledit.search` and `modaledit.selectBetween`
  commands have been refactored. Adding the new parameters described above made
  it possible to simplify the implementation and remove hacky code. The changes
  should not break existing functionality but make these commands work more
  logically and consistently. For example, both of the commands now work
  properly when they are used to extend the existing selection.

### Cursor and Status Bar Configuration

You can now define a different cursor shape when selection is active in normal
mode using the `selectCursorStyle`. Also, you can
[change the status bar text](README.html#changing-status-bar) shown in each
mode. It is possible to include icons in the status bar, if you like. This
should be sufficient to close issue
[#13](https://github.com/johtela/vscode-modaledit/issues/13)

A secondary status bar was added to show the keys that have been pressed so far.
It also shows help messages defined in bindings and  warnings from the search
command.

### Bookmark Improvements

There is a new command `modaledit.showBookmarks` that shows all the defined
bookmarks. You can jump to any of them by selecting one in the list. Also,
the bookmark can now be any string instead of a number. This actually worked
previously, but now documentation about this is updated too.

New parameter `select` in the `modaledit.goToBookmark` command extends selection
till the bookmark instead of putting the cursor on it. This makes it possible to
use bookmarks as selection scoping mechanism à la Vim.

### Changes Concerning JS Expressions

New variables `__cmd` and `__rcmd` can be used in JS expressions. They contain
the key sequence that was pressed as a string. They correspond to expressions:
```js
__cmd = __keys.join('')
__rcmd = __rkeys.join('')
```
In many cases, these variables allow you to write expressions that inspect the
key sequence in a shorter form.

All the variants of `__keys` or `__keySequence` variables now contain the actual
key sequence that was used to invoke the command. Previously they contained the
sequence that _the user_ pressed. Since you can also invoke key commands
programmatically using `modaledit.typeNormalKeys`, this made implementing
reusable commands more difficult. You could not rely on the key sequence to
correspond to the path to the keybinding you were defining. Now you can rely
that the `__keys` variable and its variants contain the path to the binding,
which should make sure that commands work correctly when invoked through
`modaledit.typeNormalKeys`.

### Other Changes

- Configuration section called `selectbindings` can be used to define key
  bindings that are in effect when selection is active. This allows you to
  define different key sequences for same leader keys in normal mode and
  selecion mode.

  For example in Vim, the `d` key is in normal mode the leader key for sequences
  such as `dw` (delete word) or `dip` (delete inside paragraph). In visual
  (selection) mode, `d` deletes the selected text. Previously it was not
  possible to have such keymaps, but with `selectbindings` you can now define
  them.

- `selecting` flag is now refreshed when you switch between files. The select
  mode no longer "sticks" between tabs.

## Version 2.1

Two new commands (courtesy of [David Little](https://github.com/haberdashPI)):

- `modaledit.enableSelection` turns selection mode on.
- `modaledit.cancelMultipleSelections` cancels selection mode preserving
  multiple cursors.

repository: johtela/vscode-modaledit

gha_language: TypeScript

repo_name: johtela/vscode-modaledit


text:
# Modern React with Redux

Udemy course by Stephen Grider([link](https://www.udemy.com/react-redux/learn/v4/overview))

## Table of Contents

<!-- TOC -->

- [Modern React with Redux](#modern-react-with-redux)
  - [Table of Contents](#table-of-contents)
  - [Progress](#progress)

<!-- /TOC -->

## Progress

- [X] *Section 01: An Intro to React* [2018-05-28]
- [X] *Section 02: AJAX Request with React* [2018-05-28]
- [X] *Section 03: Modeling Application State* [2018-06-05]
- [X] *Section 04: Managing App State with Redux* [2018-06-06]
- [X] *Section 05: Intermediate Redux: Middleware* [2018-06-06]
- [X] *Section 06: React Router + Redux Form (legacy)* [2018-06-06]
- [X] *Section 07: Bonus - RallyCoding* [2018-06-06]
  - _Finished in a separate project_
- [X] *Section 08: More to Come!* [2018-06-06]
- [X] *Section 09: React Router + Redux Form (new-version)* [2018-06-06]

repository: cesarnml/ReduxSimpleStarter

repo_name: cesarnml/ReduxSimpleStarter


text:
# TodoMVC Performance Benchmark

<img src="img/2016-07-08.png" width="504">

_(Results for Chrome 51 + OSX 10.10.5 on a Macbook Pro)_

# Try
https://developit.github.io/preact-perf

# Setup
```
npm run install
```
# Develop
```
npm run start
```
# TODO
- [ ] Collect client info.
- [ ] Average test.
- [ ] Size comparison.
- [ ] Add more framework.
- [ ] DRY test.
- [ ] Better UI/UX.

repository: developit/preact-perf

repo_name: developit/preact-perf