Friday, October 7, 2022

My Default vimrc File

 Finally putting this down, because I keep re-creating it.

The .vimrc file which normally goes in your user home dir.  There is a default in the vim install dir as well.

Suggestions welcome!




"For gVim - real GUI
set nocompatible
source $VIMRUNTIME/vimrc_example.vim
source $VIMRUNTIME/mswin.vim
behave mswin

" Disable viminfo
set viminfo=""

" to see all colors:
" ls -al /usr/share/vim/vim7*/colors
":colo evening
:colo blue
":colo slate
":colo darkblue
":colo shine

"set lines=45 columns=120

set tabstop=4 softtabstop=4 shiftwidth=4 expandtab autoindent smarttab
set nocindent
set encoding=utf-8 fileencoding=utf-8
set nobackup nowritebackup noswapfile autoread
set number ruler
set hlsearch incsearch ignorecase smartcase

"bash like auto-completion
set wildmenu
set wildmode=list:longest
"
inoremap
"
" for lusty explorer
noremap glr \lr
noremap glf \lf
noremap glb \lb

" use cntrl-h/j/k/l to switch between splits
map j
map k
map l
map h

" display the status line with the filename
set laststatus=2
set noerrorbells
set foldmethod=syntax
set ls=2
set mouse=v

" disable folding
set nofoldenable

Thursday, January 7, 2016

HTTPS Connections with Groovy using Apache HTTPClient

Sample definition of Keystores, their usage and setting up of an HTTPS client connection.

Implemented as a Groovy script, meaning there is no top-level class per se. Could probably be more concise.

//imports removed for brevity


   // Housekeeping - see what the User wants
   //   Groovy note: not declaring a var puts it into "the binding", which makes it globally accessible
   //      * this is only valid for Groovy scripts
   //      * declaring a type (or def) of a var automatically scopes it locally
   config = new Config()
   parseInput(args)

   baseUrl = "https://" + config.host + ":" + config.port + "/myapp/"

   debug "\tBase URL: " + baseUrl

   println "Loading keys..."

   // Create client keystore - this needs to contain:
   //   Client's certificate (i.e., Subject CN == clientname)
   //   Client's private key
   // Needs to be a JKS keystore
   clientKeys  = createKeystore(config.clientKeyFile, config.clientKeyPass)
                                                                                          
   // Truststore for server verification - this needs to contain:
   //   Server certificate: Subject CN == hostname
   //   Server private key
   // Needs to be a JKS keystore
   serverTrust  = createKeystore(config.serverKeyFile, config.serverKeyPass)

   debug "\tclient key: " + clientKeys
   debug "\tserver key: " + serverTrust

   try {
      // ** Create Connection **
      socketFactory = new SSLSocketFactory(
                   SSLSocketFactory.TLS,
                   clientKeys,
                   config.clientKeyPass,
                   serverTrust,
                   null,
                   new TrustSelfSignedStrategy(),                 // not a good choice for production
                   SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); // not a good choice for production

      // Connect socket to enable client PKI authentication
      HttpParams params = new BasicHttpParams();
      params.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 1000);

      SSLSocket socket = (SSLSocket) socketFactory.createSocket(params);
      socket.setEnabledCipherSuites("SSL_RSA_WITH_RC4_128_MD5");

      InetSocketAddress address = new InetSocketAddress(config.host, Integer.parseInt(config.port));
      socketFactory.connectSocket(socket, address, null, params);

      sch = new Scheme("https", new Integer(config.port), socketFactory);

      httpclient = new DefaultHttpClient();
      httpclient.getConnectionManager().getSchemeRegistry().register(sch);

      // Create a local instance of cookie store
      cookieStore = new BasicCookieStore();

      // Create local HTTP context
      localContext = new BasicHttpContext();
      // Bind custom cookie store to the local context
      localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);


      // ****** Example usage *******

      // This is the map-based impl - produces same output as the object-based
      // .... put your own data in here
      def data = [
         "_method" : "POST" ,
         "displayName" : row[DISPLAY_NAME],
         "imageUrlSmall" : row[IMAGE_URL_SMALL] ,
         "imageUrlLarge" : row[IMAGE_URL_LARGE],
         "width" : row[WIDTH],
         "height" : row[HEIGHT]
      ]

      String dataStr = JSONSerializer.toJSON(data)
      try {
         int retries = 5
         while (!created && retries-- > 0) {
         rsp = post (baseUrl + "widget", ["data":dataStr])

         matcher = rsp =~ /\"success\":([\w]+)/

         if (matcher[0]) {
            val =  matcher[0][1]
            debug "\tCREATE RESPONSE: ${val}"

            created = Boolean.parseBoolean(val)
         }

         // This is just for logging
         if (!created) {
            println "ERROR: Creation failed with response: ${rsp}"

            // Detect message failure and retry
            //   Detect failure by GUID invalid format
            matcher = rsp =~ /Property [name].*does not match the required pattern/
            if (matcher[0]) {
               debug "\tERROR RECEIVED:: name is not correct format: ${guid}"
            }
         }
         } // end while
      }
      catch (Exception e) {
          debug "Error creating listing: " + e
          e.printStackTrace()
          guid = null
      }
}

  /**
  *  Return a Keystore from a given filename and password
  */
  def KeyStore createKeystore (filename, password) {
      debug "Default KeyAlgo: " + KeyManagerFactory.getDefaultAlgorithm()
      debug "Default KeyStore: " + KeyStore.getDefaultType()  // jks

      // Pull off file extension
      keyType = filename[-3..-1]
      debug "Requested KeyType: " + keyType

      // Client keystore, for client authentication
      KeyStore keys
      switch (keyType) {
         case "p12":
            keys  = KeyStore.getInstance("pkcs12");
            break
         default:
            keys  = KeyStore.getInstance(KeyStore.getDefaultType());
      }

      FileInputStream instream = new FileInputStream(new File(filename));
      try {
         keys.load(instream, password.toCharArray());
      } finally {
         try { instream.close(); } catch (Exception ignore) {}
      }
      return keys
   }

  def post(url, paramMap) {
      HttpPost httpPost = new HttpPost(url)
      String result

      // Add specific params
      List  nvps = new ArrayList ();
      // These params always present
      nvps.add(new BasicNameValuePair("sample1", "3.6.0-GA"))
      nvps.add(new BasicNameValuePair("dojo.preventCache", "1302893700594"))

      paramMap.each() { key, value ->
         debug "${key} ==> ${value}"
         // Expect the caller to JSON-ize each param, as required
         if (value instanceof List) {
             // Add value multiple times with same key
            value.each {
               nvps.add(new BasicNameValuePair(key, it.toString()))
            }
         }
         else {
            nvps.add(new BasicNameValuePair(key, value))
         }
      }

      httpPost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8))

      // Debug
      debug(dump(httpPost))

      debug "Posting request: " + httpPost
      HttpResponse response = httpclient.execute(httpPost, localContext);
      //String response = httpclient.execute(httpPost, new BasicResponseHandler());

      debug "#### RESPONSE TYPE: " + response.class.name

      HttpEntity entity = response.getEntity();

      debug "#### RESPONSE BODY RECEIVED: " + entity.toString()

      // ** Dump results **
      debug "\t" + response.getStatusLine()
      StringBuilder sb = new StringBuilder(255)
      if (entity != null) {

         InputStream ris = entity.getContent()
         OutputStream os = new ByteArrayOutputStream(BUFFER_SIZE)
         byte[] buffer = new byte[BUFFER_SIZE];
         try {
            while ((l = ris.read(buffer)) != -1) {
                os.write(buffer, 0, l)
                sb.append(os.toString())
                os.reset()
            }
         } finally {
             ris.close()
         }

         debug "\tEntity contentLength: " + sb.length()

         result = sb?.toString()

         debug "\t-------------------------------------"
         List cookies = cookieStore.getCookies();
         for (int i = 0; i < cookies.size(); i++) {
            println("\tCookie: " + cookies.get(i));
         }                                                                                    
         debug "\t-------------------------------------"

      }
      else {
          println "Error connecting...check connection details"
          //!! EXIT HERE
          return
      }

      debug "-------------------------------------"
      if (result && result.size() > 256) {
         debug "RESPONSE: " + result.substring(0, 256)
      }
      else {
         debug "RESPONSE: " + result
      }
      debug "-------------------------------------"

      return result
  }

   def debug(stmt) {
       if (config.verbose) {
           println stmt
       }
   }

   def dump(HttpPost post) {
       StringBuilder sb = new StringBuilder(128)

       sb.append("\n\t------------------------------")
       sb.append("\n\tRequestURL: ").append(post.getURI())
       sb.append("\n\tType: ").append(post.getMethod())
       sb.append("\n\tParams: ").append(post.getParams())
       org.apache.http.params.BasicHttpParams
       sb.append("\n\t------------------------------")

       return sb.toString()
   }
         
  class Config {
      String host = "localhost"
      String port = "8443"
      boolean verbose = false
      String inputFile
      String clientKeyFile
      String clientKeyPass
      String serverKeyFile
      String serverKeyPass
  }

   def parseInput(args) {
       if (!args || args.length < 1) {
           usage()
       }
       for(int i=0; i < args.length; i++) {
           it = args[i]
           println "Processing arg: " + it
           switch (it) {
           case "-v":
               debug "Verbose output enabled "
               config.verbose = true
               break
           case "-h":
               it = args[++i]
               debug "Setting Host/Port from: " + it
               // Parse out host and port
               def serverAddr = it.split(":")
               try {
                  if (serverAddr.length > 0 && serverAddr[0] != null) {
                     config.host = serverAddr[0]
                  }
                  if (serverAddr.length > 1 && serverAddr[1] != null) {
                     config.port = serverAddr[1]
                  }
               } catch(Exception e) {
                   usage()
               }
               break
           case "-clientKeys":
               it = args[++i]
               debug "Setting client keyfile to: " + it
               config.clientKeyFile = it
               break
           case "-clientKeyPass":
               it = args[++i]
               debug "Setting client keyfile pwd to: " + it
               config.clientKeyPass = it
               break
           case "-serverKeys":
               it = args[++i]
               debug "Setting server keyfile to: " + it
               config.serverKeyFile = it
               break
           case "-serverKeyPass":
               it = args[++i]
               debug "Setting server keyfile pwd to: " + it
               config.serverKeyPass = it
               break
           default:
               debug "Setting inputFile to: " + it
               config.inputFile = it;
           }
       }
   }

Friday, December 12, 2014

Log4j Sample Config

I often seem to need a reference to log4j and can't find anything online that matches up with my expected results.

So here is my sample from a JBoss server that produces output logs:
log/server.log
log/proj-synchronization.log
log/proj-long-queries.log

What I like about this config is:
  • logs asynchronously
  • allows tuning of debug down to specific packages
  • shows routing of different packages to different output logs

NOTE: many blocks are commented out and left in as examples -- I've tried to denote these by separating their header line.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<!-- ===================================================================== -->
<!--                                                                       -->
<!--  Log4j Configuration                                                  -->
<!--                                                                       -->
<!-- ===================================================================== -->

<!-- $Id: log4j.xml 56612 2006-09-07 15:12:39Z thomas.diesler@jboss.com $ -->

<!--
   | For more configuration information and examples see the Jakarta Log4j
   | website: http://jakarta.apache.org/log4j
 -->

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">

   <!-- ================================= -->
   <!-- Preserve messages in a local file -->
   <!-- ================================= -->

   <!-- A time/date based rolling appender -->
   <appender name="FILE" class="org.jboss.logging.appender.DailyRollingFileAppender">
      <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
      <param name="File" value="${jboss.server.log.dir}/server.log"/>
      <param name="Append" value="false"/>
      <param name="Threshold" value="DEBUG"/>

     <param name="MaxFileSize" value="100KB"/>

      <!-- Rollover at midnight each day -->
      <param name="DatePattern" value="'.'yyyy-MM-dd"/>

      <!-- Rollover at the top of each hour
      <param name="DatePattern" value="'.'yyyy-MM-dd-HH"/>
      -->

      <layout class="org.apache.log4j.PatternLayout">
         <!-- The default pattern: Date Priority [Category] Message\n -->
         <param name="ConversionPattern" value="%d [%t] %-5p [%c] %m%n"/>

         <!-- The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
         <param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
          -->
      </layout>
   </appender>

   <appender name="PROJ-SYNCHRONIZATION" class="org.jboss.logging.appender.DailyRollingFileAppender">
      <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
      <param name="File" value="${jboss.server.home.dir}/log/proj-synchronization.log"/>
      <param name="Append" value="true"/>
      <param name="DatePattern" value="'.'yyyy-MM-dd"/>
      <layout class="org.apache.log4j.PatternLayout">
         <param name="ConversionPattern" value="%d [%t] %-5p [%c] %m%n"/>
      </layout>
   </appender>

   <appender name="PROJ-WEBSERVICE" class="org.jboss.logging.appender.DailyRollingFileAppender">
      <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
      <param name="File" value="${jboss.server.home.dir}/log/proj-webservice.log"/>
      <param name="Append" value="true"/>
      <param name="DatePattern" value="'.'yyyy-MM-dd"/>
      <layout class="org.apache.log4j.PatternLayout">
         <param name="ConversionPattern" value="%d [%t] %-5p [%c] %m%n"/>
      </layout>
   </appender>

   <appender name="QUERY" class="org.jboss.logging.appender.DailyRollingFileAppender">
      <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
      <param name="File" value="${jboss.server.home.dir}/log/proj-long-queries.log"/>
      <param name="Append" value="true"/>
      <param name="DatePattern" value="'.'yyyy-MM-dd"/>
      <layout class="org.apache.log4j.PatternLayout">
         <param name="ConversionPattern" value="%d [%t] %-5p [%c] %m%n"/>
      </layout>
   </appender>


   <!-- A size based file rolling appender

   <appender name="FILE" class="org.jboss.logging.appender.RollingFileAppender">
     <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
     <param name="File" value="${jboss.server.log.dir}/server.log"/>
     <param name="Append" value="false"/>
     <param name="MaxFileSize" value="500KB"/>
     <param name="MaxBackupIndex" value="1"/>

     <layout class="org.apache.log4j.PatternLayout">
       <param name="ConversionPattern" value="%d %-5p [%c] %m%n"/>
     </layout>       
   </appender>
   -->

   <!-- ============================== -->
   <!-- Append messages to the console -->
   <!-- ============================== -->
   <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
      <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
      <param name="Target" value="System.out"/>
      <param name="Threshold" value="INFO"/>

      <layout class="org.apache.log4j.PatternLayout">
         <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/>
      </layout>
   </appender>

   <!-- ====================== -->
   <!-- More Appender examples -->
   <!-- ====================== -->

   <!-- Buffer events and log them asynchronously -->
   <appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
     <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
     <appender-ref ref="FILE"/>
     <appender-ref ref="CONSOLE"/>
     <appender-ref ref="SMTP"/>
   </appender>

   <!-- EMail events to an administrator

   <appender name="SMTP" class="org.apache.log4j.net.SMTPAppender">
     <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
     <param name="Threshold" value="ERROR"/>
     <param name="To" value="admin@myhost.domain.com"/>
     <param name="From" value="nobody@myhost.domain.com"/>
     <param name="Subject" value="JBoss Sever Errors"/>
     <param name="SMTPHost" value="localhost"/>
     <param name="BufferSize" value="10"/>
     <layout class="org.apache.log4j.PatternLayout">
       <param name="ConversionPattern" value="[%d{ABSOLUTE},%c{1}] %m%n"/>
     </layout>
   </appender>
   -->

   <!-- Syslog events

   <appender name="SYSLOG" class="org.apache.log4j.net.SyslogAppender">
     <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
     <param name="Facility" value="LOCAL7"/>
     <param name="FacilityPrinting" value="true"/>
     <param name="SyslogHost" value="localhost"/>
     <layout class="org.apache.log4j.PatternLayout">
       <param name="ConversionPattern" value="[%d{ABSOLUTE},%c{1}] %m%n"/>
     </layout>
   </appender>
   -->

   <!-- Log events to JMS (requires a topic to be created)

   <appender name="JMS" class="org.apache.log4j.net.JMSAppender">
     <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
     <param name="Threshold" value="ERROR"/>
     <param name="TopicConnectionFactoryBindingName" value="java:/ConnectionFactory"/>
     <param name="TopicBindingName" value="topic/MyErrorsTopic"/>
   </appender>
   -->

   <!-- Log events through SNMP

   <appender name="TRAP_LOG" class="org.apache.log4j.ext.SNMPTrapAppender">
     <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
     <param name="ImplementationClassName" value="org.apache.log4j.ext.JoeSNMPTrapSender"/>
     <param name="ManagementHost" value="127.0.0.1"/>
     <param name="ManagementHostTrapListenPort" value="162"/>
     <param name="EnterpriseOID" value="1.3.6.1.4.1.24.0"/>
     <param name="LocalIPAddress" value="127.0.0.1"/>
     <param name="LocalTrapSendPort" value="161"/>
     <param name="GenericTrapType" value="6"/>
     <param name="SpecificTrapType" value="12345678"/>
     <param name="CommunityString" value="public"/>
     <param name="ForwardStackDEBUGWithTrap" value="true"/>
     <param name="Threshold" value="DEBUG"/>
     <param name="ApplicationTrapOID" value="1.3.6.1.4.1.24.12.10.22.64"/>
     <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d,%p,[%t],[%c],%m%n"/>
     </layout>
   </appender>
   -->

   <!--  Emit events as JMX notifications

   <appender name="JMX" class="org.jboss.monitor.services.JMXNotificationAppender">
      <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
     
      <param name="Threshold" value="WARN"/>
      <param name="ObjectName" value="jboss.system:service=Logging,type=JMXNotificationAppender"/>
     
      <layout class="org.apache.log4j.PatternLayout">
         <param name="ConversionPattern" value="%d %-5p [%c] %m"/>
      </layout>
   </appender>
   -->
  
   <!-- ================ -->
   <!-- Limit categories -->
   <!-- ================ -->

   <!-- Limit the org.apache category to INFO as its DEBUG is verbose -->
   <category name="org.apache">
      <priority value="ERROR"/>
   </category>

   <category name="org.apache.log4j">
      <priority value="DEBUG"/>
   </category>


   <!-- Limit the org.jboss.serial (jboss-serialization) to INFO as its DEBUG is verbose -->
   <category name="org.jboss.serial">
      <priority value="ERROR"/>
   </category>

   <!-- Limit the org.jgroups category to WARN as its INFO is verbose -->
   <category name="org.jgroups">
      <priority value="ERROR"/>
   </category>

   <!-- Limit the jacorb category to WARN as its INFO is verbose -->
   <category name="jacorb">
      <priority value="ERROR"/>
   </category>

   <!-- Limit JBoss categories  -->
   <category name="org.jboss">
      <priority value="ERROR"/>
   </category>

   <category name="org.springframework">
      <priority value="ERROR"/>
   </category>

   <category name="org.springframework.web">
      <priority value="error"/>
   </category>

   <category name="org.springframework.scheduling">
      <priority value="error"/>
   </category>

   <category name="org.quartz">
      <priority value="error"/>
   </category>

   <category name="javawebparts">
      <priority value="ERROR"/>
   </category>

   <!-- Limit the JSR77 categories -->
   <category name="org.jboss.management">
      <priority value="ERROR"/>
   </category>

   <category name="org.hibernate">
      <priority value="warn"/>
   </category>

   <category name="org.hibernate.SQL">
      <priority value="warn"/>
   </category>

   <category name="net.sf.ehcache">
      <priority value="ERROR"/>
   </category>

   <category name="com.proj.ws">
      <priority value="error"/>
   </category>

   <category name="com.myapp">
      <priority value="DEBUG"/>
   </category>
   <category name="com.myapp.service">
      <priority value="DEBUG"/>
   </category>
   <category name="com.myapp.spring">
      <priority value="DEBUG"/>
   </category>

   <category name="com.myapp.service.UserService">
      <priority value="error"/>
   </category>

   <!-- Flooring utils are not usually useful in troubleshooting -->
   <category name="com.myapp.util">
      <priority value="DEBUG"/>
   </category>

   <category name="com.myapp.servlet.filter">
      <priority value="DEBUG"/>
   </category>

   <category name="com.proj.ws.synchronization" additivity="false">
      <priority value="error"/>
      <appender-ref ref="PROJ-SYNCHRONIZATION"/>
   </category>

   <category name="com.proj.ws.longQuery" additivity="false">
      <priority value="ERROR"/>
      <appender-ref ref="QUERY"/>
   </category>

   <!-- Enable JBossWS message tracing
    <priority value="error" class="org.jboss.logging.XLevel"/>
   -->
   <category name="jbossws.SOAPMessage">
     <priority value="error"/>
   </category>

   <!-- Decrease the priority threshold for the org.jboss.varia category -->
   <category name="org.jboss.varia">
     <priority value="error"/>
   </category>

   <!-- Show the evolution of the DataSource pool in the logs [inUse/Available/Max]

   <category name="org.jboss.resource.connectionmanager.JBossManagedConnectionPool">
     <priority value="error" class="org.jboss.logging.XLevel"/>
   </category>
   -->

   <!--

      | An example of enabling the custom DEBUG level priority that is used
      | by the JBoss internals to diagnose low level details. This example
      | turns on DEBUG level msgs for the org.jboss.ejb.plugins package and its
      | subpackages. This will produce A LOT of logging output.
   <category name="org.jboss.system">
     <priority value="DEBUG" class="org.jboss.logging.XLevel"/>
   </category>
   <category name="org.jboss.ejb.plugins">
     <priority value="DEBUG" class="org.jboss.logging.XLevel"/>
   </category>
   -->
 
   <!--
       | Logs these events to SNMP:

           - server starts/stops
           - cluster evolution (node death/startup)
           - When an EJB archive is deployed (and associated verified messages)
           - When an EAR archive is deployed
         
   <category name="org.jboss.system.server.Server">
     <priority value="INFO" />
     <appender-ref ref="TRAP_LOG"/>
   </category>
 
   <category name="org.jboss.ha.framework.interfaces.HAPartition.lifecycle">
     <priority value="INFO" />
     <appender-ref ref="TRAP_LOG"/>
   </category>

   <category name="org.jboss.deployment.MainDeployer">
     <priority value="ERROR" />
     <appender-ref ref="TRAP_LOG"/>
   </category>
  
   <category name="org.jboss.ejb.EJBDeployer">
     <priority value="INFO" />
     <appender-ref ref="TRAP_LOG"/>
   </category>
  
   <category name="org.jboss.deployment.EARDeployer">
     <priority value="INFO" />
     <appender-ref ref="TRAP_LOG"/>
   </category>
 
   -->

   <!-- ======================= -->
   <!-- Setup the Root category -->
   <!-- ======================= -->

   <root>
       <appender-ref ref="FILE"/>
       <appender-ref ref="CONSOLE"/>
       <!-- use if routing all categories to an appender-ref <level value="OFF" /> -->
   </root>

   <!-- Clustering logging -->

   <!-- Uncomment the following to redirect the org.jgroups and
      org.jboss.ha categories to a cluster.log file.

   <appender name="CLUSTER" class="org.jboss.logging.appender.RollingFileAppender">
     <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
     <param name="File" value="${jboss.server.log.dir}/cluster.log"/>
     <param name="Append" value="false"/>
     <param name="MaxFileSize" value="500KB"/>
     <param name="MaxBackupIndex" value="1"/>

     <layout class="org.apache.log4j.PatternLayout">
       <param name="ConversionPattern" value="%d %-5p [%c] %m%n"/>
     </layout>
   </appender>
   <category name="org.jgroups">
     <priority value="DEBUG" />
     <appender-ref ref="CLUSTER"/>
   </category>
   <category name="org.jboss.ha">
     <priority value="DEBUG" />
     <appender-ref ref="CLUSTER"/>
   </category>
   -->

</log4j:configuration>

Friday, August 16, 2013

Viewing Markdown files in Firefox on Linux

There are Firefox plugins for viewing Markdown files - but neither of the big ones - Markdown Editor and Markdown Viewer - worked at all on my linux distro (Mint 15), even with the mimetypes.rdf workaround. There are of course editors like UberWriter that will do some special formatting of MD files, but none I have found really track well to the actual HTML produced by the browser plugins. Since many of my colleagues use Firefox on Windows where the plugins work, I wanted to know what they would look like. In desperation I hacked a quick and dirty solution using a Python translator, markdown2.
  • first install pip

    sudo apt-get install python-pip
  • install markdown2
    pip install markdown2
  • for me this had already run 'python setup.py install'
    • if it doesn't for you then run manually
  • test at command line - should be available
    markdown2
  • now try all together - assumes firefox is on your path
    markdown2 README.MD > README.html; firefox README.html
  • add as a shell alias - modify ~/.bashrc and add

       function mark() { 
          markdown2 "$@" > "$@".html; 
         firefox "$@".html
       }
    
  • now try
    source ~/.bashrc 
    mark README.MD
    

Tuesday, June 25, 2013

PKI Security Cheat Sheet

This is a work in progress.

----------------------------------------------------------------------
Using OpenSSL - most common activities
----------------------------------------------------------------------

Generally used for X509 artifacts, i.e. the more open standard.

Dump X509 certificate(CRT) content - assumes PEM format
openssl x509 -in certificate.crt -text -noout

Dump X509 certificate(CRT) content - specify input format, PEM/DER
openssl x509 -inform DER -in site.crt
NB:Try changing the format on error: "Expecting: TRUSTED CERTIFICATE"

Dump a pkcs12 user identity certificate
openssl pkcs12 -info -in keyStore.p12

Dump private key content
openssl rsa -in host.key -text

----------------------------------------------------------------------
Using OpenSSL - creating and modifying keys
----------------------------------------------------------------------


Create a private key
openssl req -out CSR.csr -new -newkey rsa:2048 -nodes -keyout privateKey.key

----------------------------------------------------------------------
Using keytool - most common activities
----------------------------------------------------------------------

Generally used for working with Java keystore(JKS) files.

List contents of a JKS
keytool -list -v -keystore keystore.jks

Dump a cert
keytool -printcert -v -file host.crt

Export a cert from a JKS for given alias
keytool -export -alias sitename -file sitename.crt -keystore keystore.jks

List default JVM CA certs
keytool -list -v -keystore $jAVA_HOME/jre/lib/security/cacerts

----------------------------------------------------------------------
Debugging an SSL Connection
----------------------------------------------------------------------

You are trying to set up a Java webserver fronting SSL and having issues.

Test the connection using openSSL to see what SSL it supports
openssl s_client -connect mysite.com:443

Enable SSL debug
Add the following to the JVM startup command:
-Djavax.net.debug=[ssl|all]

and see this to understand the output.
This will often lead you to the cause of the connection issues.

----------------------------------------------------------------------
Resources
----------------------------------------------------------------------

Tuesday, April 16, 2013

Citrix on Linux

When I first starting using Linux, one serious issue I had was connecting to my clients' desktops using Citrix - aka the Xen Desktop.

After a while I found a solution.  This is how I have to interact with a Citrix session from my Linux distro (Mint 14). Relevant for v12.1.0 of the icaclient for Linux.  

Installing
  • download the Receiver (icaclient) at http://www.citrix.com/downloads/citrix-receiver/receivers-by-platform/receiver-for-linux-121.html
  • choose the .deb version for Debian/dpkg install
  • attempt install - it will fail with a problem in the postinst script
    •  uname -m architecture is not expected
  • apply this workaround:
  • complete installation

  • access to Citrix connections from Firefox should work now
  • Running
    • set desktop Panel to Auto-Hide (right-click on taskbar, Panel Settings) 
      • due to BUG: which offsets mouse position by your taskbar width
    • connect to Citrix and launch a desktop
    • if it launches maximized, unmaximize
      • due to BUG: running maximized can cause latency in keyboard strokes
    • if right-click on titlebar shows 2 context menus (instead of one), minimize then re-store the window
    • (attempt to) move the window by dragging the titlebar over to the right a little bit
    • now resize the window frame by pulling out on the right side
    • should be ready

Saturday, March 23, 2013

Git Cheat Sheet


Your Best Reference Pro Git -- download for PDF, ePub or Mobi formats here http://git-scm.com/book

Tip: Use Calibre's built-in server to push the ePub to your smartphone.


----------------------------------------------------------------------
Basic Git - Startup
----------------------------------------------------------------------


Basic Git Architecture
  • Decentralized - everybody's copy of a project is a full database copy
  • versions not stored as deltas - instead they are stored as complete instances of the files
  • all content is compressed in the database
Basic Git Lifecycle
  • new file => Untracked --> files unknown to Git
  • 'git add' => Staged --> ready for commit, file or version not yet in database
  • 'get commit' => Tracked --> file/version tracked in the database
Even Tracked files, once modified, require Staging again! i.e. you must 'git add' again!!!

Configuring Your Global Identity - Do this when first installing Git.

Set name
> git config --global user.name "Your Name"
Set email address
> git config --global user.email you@example.com

Create New Project
Create source directory. Create as a Git repo via:
> git init

Unlike SVN/CVS/VSS, the repo lives in your project directory. It's OK.
Ignore Files with .gitignore
  • Put .gitignore at the project top level directory
  • Add a line per filter; example:
# this is a comment
     *.class
     logs/
  • this example excludes all class files, and the logs directory

----------------------------------------------------------------------
Basic Git - Typical Workflow
----------------------------------------------------------------------


See what has Changed
> git status

Commit Tracked, Modified Files
> git add -u
> git commit -m "notes about the commit"
Show changes to tracked files that are NOT staged
> git diff
Show changes to tracked files that ARE staged for commit
> git diff --staged (or --cached, an alias)

Add an Untracked File
> git add <filename>

Revert changes to a tracked file:
> git checkout -- <filename>

Revert a Staged File
It got added to stage area, but you don't want to commit it yet
> git reset HEAD <filename>

Revert all Staged Files
Unstages all from the staging area - maybe you ran 'git add .' and .gitignore did not filter properly
> git reset HEAD

Temporarily Switch to Another Branch
Got some changes not ready for committing, but need to pop to another branch - stash the current work
> git stash

Switch to another branch (git checkout)
Then come back and reapply latest stashed changes
> git stash apply

Or see list of stashes
> git stash list
And apply a named stash
> get stash apply stash@{1}

Pull Updates from a Remote Repo
Typical - when you're working with a team
- the rebase keeps the history cleaner by moving your local commits to after the new merges
> git pull --rebase

----------------------------------------------------------------------
Basic Git - Details
----------------------------------------------------------------------


Add a New File
create a README.md - this stages it
> git add README.md
and commit
> git commit -m "initial" README.md
Commit All Changed Files
Stage any changed files
> git add .
See what is staged
> git status
Commit
> git commit -m "your message"
Do all at once
> git add -A && git commit -m "your message"
Or use -a to skip staging (the 'git add' part)
> git -a -m "message"
Revert a Staged File
It got added to stage area, but you don't want to commit it yet
> git reset HEAD <filename>
Revert all Staged Files
Unstages all from the staging area
> git reset HEAD
Revert all Changes on the Branch
Don't like where the branch is going? Undo all changed files
> git checkout -f
Revert changes to a tracked file:
> git checkout -- <filename>
Revert a commit
There are myriad solutions, see here
http://stackoverflow.com/questions/927358/how-to-undo-the-last-git-commit
See What is Modified
Show any modified or untracked files
> git status
Show changes to tracked files that are NOT staged
> git diff
Show changes to tracked files that ARE staged for commit
> git diff --staged (or --cached, an alias)
Committing a File
Check for annoying whitespace changes
> git diff --check
See what changed - shows patch diffs
> git log -p filename
Commit and enter comment editor
> git commit README.md Conventional commit comment:
  • 50-char summary, followed by...
  • blank line, followed by...
  • detailed description of change
View Commit Histories
See all changes, ever
> git log
And for a certain file
> git log -2 filename
Just the last 2 commits
> git log -2
Last commit with patch diffs
> git log -p -1
Commits since a certain date
> git log --since 1.week
> git log --since 10.days
> git log --since 2013-02-03
Commits in date range
> git log --since 2.weeks --until 1.week
Commits by committer (modifier of file)
> git log --committer username
See 'gitk' for a visual git log UI
Changing Last Commit
Add some files to the last commit. Adds whatever is staged:
> git commit --amend
Change the commit comments - assumes nothing is staged:
> git commit --amend -m "new message"
Deleting Committed Files
Just a single file, locally and from repo
> git rm filename.txt
A directory of files, locally and from repo
> git -r rm dirName
A directory of files, but ONLY from the repo, not local copies
> git -r --cached rm dirName
A file that was already staged:
> git -f filename.txt
Requires commit afterwards.
Renaming a File
Not explicitly supported internally, but calculated; and a convenience function:
> git mv oldname.txt newname.txt
Requires commit afterwards.
----------------------------------------------------------------------
Tagging
----------------------------------------------------------------------

Listing existing Tags
> git tag
Using wildcards to find tags
> git tag -l 'v1.2*'

Using a Tag
> git checkout

Creating a lightweight Tag
Example for v1.0; lightweight tags are just pointer sets
> git tag v1.0

Creating an Annotated Tag
These are checksummed and contain annotation, and optional signature
> git tag -a v1.0 -m 'release 1.0'

Creating a Signed Tag
Must have a private key installed
> git tag -s v1.0 -m 'release 1.0'

Tagging After the Fact
Forgot to tag? No matter, find the relevant commit
> git log --pretty=oneline
And tag using the checksum (first 6 or 7 characters of the checksum)
> git tag -a v1.2 9fceb02
And verify
> git show v1.2

Sharing Tags with Remotes
Tags must be pushed out like branches are
> git push origin v1.5

Or, all at once
> git push origin --tags

----------------------------------------------------------------------
Branching and Merging
----------------------------------------------------------------------

Show Current Branch
Currently checked-out branch
> git branch

List All Existing Branches
Show all branches - star is currently checked out
> git branch -v (verbose gives info on last commit)

Creating a Branch
Create new branch based on some other branch
> git checkout -b new-branch existing-branch

Create new local branch from current, and immediately check it out
> git checkout -b newbranch

Create new local branch from the remote master branch, and immediately check it out
> git checkout -b newbranch origin/master

Merge one local branch into another
This merges feature into master
> git checkout master
> git merge feature

Merge branch from remote repo into local repo
First update local copy of remote
> git fetch origin
Look at changes to remote branch
> git log origin/featureA ^featureA (not sure what the ^ is)
Merge into local branch (checkout first if necessary)
> git merge origin/featureA

Deleting a Branch
Must not be your current branch, and must not have outstanding changes
> git branch -d >branch<

----------------------------------------------------------------------
Creating a Repository on GitHub
----------------------------------------------------------------------


You created a project and want to post it to share with colleagues.
Locally you did this:
    ir="ltr">create local Git repo
> git init
  • Do work
  • Commit files
On GitHub you do this
  • Create Repo (there is a magic button)
  • Note the new project URL (ending in .git)
Then locally, do this:
> git remote add origin <new git URL, ends in .git>
> git remote -v (examine your remotes)
> git push -u origin master (or whatever branch name you're working in


----------------------------------------------------------------------
Working with Remote Repositories
----------------------------------------------------------------------

A Remote is an alias to a remote repository.

Show List of Remotes
See list of known remotes
> git remote -v

Add alias to a remote repo - alias is often 'origin' by convention
> git remote add <alias> [root project URL ending in .git]

Uploading to a Remote
Upload branch contents to a named remote (origin)

Uploading a Branch to Someone Else's Repo
When branch name is the same
> git -u push <alias> <branch-name>
...example:
> git push -u origin master

When branch name is different on remote
> git -u push <alias> <local-branch-name>:<remote-branch-name>
...example:
> git -u push origin featureX:patch331

The -u option sets up a upstream branch - i.e. maps local to remote branch.

Getting changes from Remote Repo
Doing this will do a 'fetch' followed by a 'merge' - i.e. get you up to date
Pull will always merge into the current branch; specify which branch to pull from:
> git pull

Fetch is less damaging - not sure yet how to use effectively
> get fetch


----------------------------------------------------------------------
Working with GitHub Repos
----------------------------------------------------------------------

There's a project you want to get some changes into. Do this.

1. Look at the project's GitHub page; see 'Network' and 'Issues' tags.
Make sure someone else isn't already doing what you wanted to do.
2. On the GitHub page, press 'Fork' to create your own repo.
3. Clone the fork locally using its new URL
> git clone [url of my fork] <my local dir>
5. Add the fork Repo as a remote
> git remote add origin <fork URL ending in .git>
6. Add the orginal Repo as a remote for easy updating (to stay sync'd)
> git remote add upstream <original project URL ending in .git>

Contributing to Projects - Go with the Flow
Different projects may have different workflows - find out by reading the project README.
This can vary based on project size and organizer preference.

Simple Workflow Example
A simple contribution workflow looks like this:
  • developer forks project
  • clones fork locally ( steps 1-6 above)
  • does work in topic branches - not master!
  • pushes topic branches up to fork repo
  • submits pull request to original project via GitHub
The Steps
1. Do initial Fork setup, steps 1-6 above

2. Create a Topic Branch
This is a branch for doing local work in
> git checkout -b new-feature origin/master

3. Keep Local work in synch
Synch with the original project - first get all its branches and updates
> git fetch upstream
Merge its change into your working branch - where 'master' is the remote branch to merge in
> git merge upstream/master

4. Do work
Do work in the topic branch ('new-feature' above) as usual
Stage and Commit when ready
Periodically merge in remote changes (#3)

5. Push changes out to your Fork repo
> git push origin new-feature

6. When Ready
Good tests are included? Bugs are out?
Log into your Github fork project and switch branches (using selector) to your new-feature branch
Verify contents; update Readme file
Navigate to original project and submit a Pull Request

Linux Cheat Sheet

  ---------------------------------------------------------------------- Hardware ----------------------------------------------------------...