Thursday, November 30, 2017

Print a given line of a text file in bash

1. fos@ubuntu:~/dev/java$ head -n 4 HelloWorld.java  |tail -1
public class HelloWorld {

2. fos@ubuntu:~/dev/java$ sed -n '4p' HelloWorld.java
public class HelloWorld {

fos@ubuntu:~/dev/java$ sed  '4!d' HelloWorld.java
public class HelloWorld {

fos@ubuntu:~/dev/java$ sed '4q;d' HelloWorld.java    # efficient on large files
public class HelloWorld {

3. fos@ubuntu:~/dev/java$ ex +4p -scq HelloWorld.java
public class HelloWorld {

4. fos@ubuntu:~/dev/java$ awk 'FNR==4 {print $0}' HelloWorld.java
public class HelloWorld {

5. .....

Java version in the .class file

Exception in thread "main" java.lang.UnsupportedClassVersionError: org/eclipse/jetty/util/security/Password : Unsupported major.minor version 52.0

java.lang.UnsupportedClassVersionError happens because of a higher JDK during compile time and lower JDK during runtime.


1. fos@ubuntu:~/dev/java$ javap -v HelloWorld |grep version
  minor version: 0
  major version: 52
2. fos@ubuntu:~/dev/java$ file HelloWorld.class
HelloWorld.class: compiled Java class data, version 52.0 (Java 1.8)

3. Find the value in 6th and 7th bytes:
Within Emacs:
87654321  0011 2233 4455 6677 8899 aabb ccdd eeff  0123456789abcdef
00000000: cafe babe 0000 0034 0041 0a00 1000 1d07  .......4.A......

Or Use hexdump:
fos@ubuntu:~/dev/java$ hexdump HelloWorld.class |more
0000000 feca beba 0000 3400 4100 000a 0010 071d

0x34 = 52  <--- 8="" is="" java="" p="" this="">


Here's the list of versions:

Java SE 9 = 53,
Java SE 8 = 52,
Java SE 7 = 51,
Java SE 6.0 = 50,
Java SE 5.0 = 49,
JDK 1.4 = 48,
JDK 1.3 = 47,
JDK 1.2 = 46,
JDK 1.1 = 45

More:
The class file format: https://docs.oracle.com/javase/specs/jvms/se6/html/ClassFile.doc.html

Tuesday, November 7, 2017

GDB cheatsheet

 gdb -args ./binary arg1 arg2 ...

set print pretty on
p *var1
p *var1@len

gdb -tui. tui stands for Text User Interface
C-x a to show/hide source code and assembly code window
C-x 1 to show only source code window
C-x 2 to show only assembly code window



Tuesday, October 24, 2017

Friday, September 29, 2017

handle JSON with jansson in C


int main()
{
    printf("Hello jansson...\n");

    const char * data_str = "{\
              \"operation\":\"mark-tier-movement\",\
              \"mark_tier_movement_request\":{\
                  \"mark_tier_movement\":true\
              }\
      }";

    json_t *root;
    json_error_t error;
    root = json_loads(data_str, 0, &error);
    if (!root) {
        printf("error: on line %d: %s\n", error.line, error.text);
        return 1;
    }

    json_t *operation;
    const char *msg_txt;
    operation = json_object_get(root, "operation");
    msg_txt = json_string_value(operation);
    printf("operation is: %s\n", msg_txt);

    return 0;
}

[root@localhost dev]# ./demo
Hello jansson...
operation code: is: mark-tier-movement

Friday, August 25, 2017

Add a new virtual hard disk to your Linux VM

1. log in as root
2. run this command and make note of the sdx entries
[root@localhost ~]# ls -l /dev/sd*
brw-r----- 1 root disk 8,  0 Aug 25 03:46 /dev/sda
brw-r----- 1 root disk 8,  1 Aug 25 10:46 /dev/sda1
brw-r----- 1 root disk 8,  2 Aug 25 03:46 /dev/sda2
brw-r----- 1 root disk 8,  3 Aug 25 03:46 /dev/sda3
brw-r----- 1 root disk 8,  4 Aug 25 10:46 /dev/sda4

3.  Add a new virtual hard disk to your VM from VMware Workstation GUI

4. run this command and you'll see the new entry for your newly added disk
[root@localhost ~]# ls -l /dev/sd*
brw-r----- 1 root disk 8,  0 Aug 25 03:46 /dev/sda
brw-r----- 1 root disk 8,  1 Aug 25 10:46 /dev/sda1
brw-r----- 1 root disk 8,  2 Aug 25 03:46 /dev/sda2
brw-r----- 1 root disk 8,  3 Aug 25 03:46 /dev/sda3
brw-r----- 1 root disk 8,  4 Aug 25 10:46 /dev/sda4
brw-r----- 1 root disk 8, 16 Aug 25 03:46 /dev/sdb

5. check your current file system type, it is ext3 for /
[root@localhost ~]# mount |grep ^/dev
/dev/sda4 on / type ext3 (rw)
/dev/sda2 on /tmp type ext2 (rw)
/dev/sda1 on /boot type ext3 (rw)

6. Check disk size and partition table with fdisk
[root@localhost ~]# fdisk -l

Disk /dev/sda: 21.4 GB, 21474836480 bytes
255 heads, 63 sectors/track, 2610 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          65      522081   83  Linux
/dev/sda2              66         326     2096482+  83  Linux
/dev/sda3             327         587     2096482+  82  Linux swap / Solaris
/dev/sda4             588        2610    16249747+  83  Linux

Disk /dev/sdb: 26.8 GB, 26843545600 bytes
255 heads, 63 sectors/track, 3263 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Disk /dev/sdb doesn't contain a valid partition table

7. create an ext3 file system on the whole new disk
$ mkfs -t ext3 /dev/sdb


8. make directory as mount point
$ mkdir /bld

9. edit fstab for a permanent mount
/dev/sdb                 /bld                   ext3    defaults        0 0

10. reboot your VM



RCA: data type is incorrect

QA reported one issue during regression test. He added one Hbase backup configuration via GUI but the backup operation failed. HDFS backup is OK.

Looking into this issue, I found the data type is saved as "HDFS" in the configuration file which should be "HBASE" in the URL. It narrows down the problem.

Looking back to a recent checkin by a team member, I found this:
184:                   if ($scope.editdatamodel.bkCfg.type == "hbase") {
185:                        value = "/" + value;
186:                        basedir.replace("hdfs://", "hbase://");
187:                    }
Look at line 186. Yes, that's the root cause.  The javascript function 'replace' does not search and replace in place. It returns a NEW string.
https://www.w3schools.com/jsref/jsref_replace.asp

Solution:
    basedir = basedir.replace("hdfs://", "hbase://");

Friday, July 28, 2017

Uninstall git which is installed from source

I installed git 2.9.4 from source code via 'configure' and 'make install'. For some reason I need to uninstall it, but it could not be uninstalled with 'make uninstall'.

sudo find /usr/local -depth -iname 'git*' -exec rm -rf {} \;

The above command would delete all git related files.

Failed to start CentOS with GUI

When I came back from vacation, I could not start up my Cloudera Sandbox. It failed with the error message:

problem with the configuration server (/usr/libexec/gconf-sanity-check-2 exited with status 256

To fix it, press CTRL+ALT+F2 to switch to a Linux Terminal and then login with root,  then change the permission of /tmp to 777.

Restart it. All good to go.

Tuesday, June 27, 2017

Run a command with ProcessBuilder in Java

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Jceks {
    public static void main(String[] args) {
        System.out.println("Hello jceks...");
        System.out.println(Arrays.toString(args));
        try {
            run(args);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    public static void run(String[] command) throws Exception {
        System.out.println(String.join(" ", command));

        int exitCode = 0;
        StringBuilder output = new StringBuilder();
        ProcessBuilder pb = new ProcessBuilder(command);
        pb.redirectErrorStream(true);

        Process p = pb.start();
        exitCode = p.waitFor();

        BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line;
        while ((line = reader.readLine())!= null) {
            output.append(line + "\n");
        }

        System.out.println(output);
    }
}

Thursday, June 22, 2017

RCA: /usr/java/jre1.8.0_112/bin/bin/java: No such file or directory

QA reported one issue observed in their environment:
Searching for java...
        1. /usr/java/jdk1.6.0_31/bin/java
        2. /usr/java/jdk1.6.0_31/jre/bin/java
        3. /usr/java/jdk1.7.0_67-cloudera/bin/java
        4. /usr/java/jdk1.7.0_67-cloudera/jre/bin/java
        5. /usr/java/jre1.8.0_112/bin/java
        6. Specify location of java to use.
Type the number for the required java from this list: [1] 5

/opt/cloudera/parcels/CDH-5.4.4-1.cdh5.4.4.p0.4/bin/../lib/hadoop/bin/hadoop: line 144: /usr/java/jre1.8.0_112/bin/bin/java: No such file or directory

/opt/cloudera/parcels/CDH-5.4.4-1.cdh5.4.4.p0.4/bin/../lib/hadoop/bin/hadoop: line 144: exec: /usr/java/jre1.8.0_112/bin/bin/java: cannot execute: No such file or directory
Note that the choice in the list is correct, but the script then invokes a “bin/bin/java” – where did it get that from?


Well, well, at the beginning I thought there was something wrong in our script using the specified Java directory(JAVA_HOME, PATH). While digging deeper, the error comes from:
-bash-3.2# /usr/bin/hadoop classpath --glob
/opt/cloudera/parcels/CDH-5.4.4-1.cdh5.4.4.p0.4/bin/../lib/hadoop/bin/hadoop: line 144: /usr/java/jre1.8.0_112/bin/bin/java: No such file or directory

/opt/cloudera/parcels/CDH-5.4.4-1.cdh5.4.4.p0.4/bin/../lib/hadoop/bin/hadoop: line 144: exec: /usr/java/jre1.8.0_112/bin/bin/java: cannot execute: No such file or directory

Check JAVA_HOME:
-bash-3.2# echo $JAVA_HOME
/usr/java/jre1.8.0_112/bin
-bash-3.2#

OMG, The above $JAVA_HOME is incorrect.

THE JAVA_HOME/JRE_HOME should be the installation directory, not the bin directory under it.

Correct it with

-bash-3.2# export JAVA_HOME=/usr/java/jre1.8.0_112

Documentation from Oracle:
https://docs.oracle.com/cd/E19182-01/820-7851/inst_cli_jdk_javahome_t/


RCA: boost::filesystem::permissions: Operation not permitted

There is a configuration file, say /our/product/config.json, in our product.  It was designed with permission 644 which means only the owner of this configuration can update its content. This makes it impossible to support multiple users since each user should be able to update this configuration file by design.

A fix was submitted to address this issue with:
    pt::write_json(...)
    changePermission(666)

The first line will create the configuration file if it does not exist or update it if it has already been created. Note that the 2nd line will set permission as 666 every time this file is created/updated -- a new problem arises:
    boost::filesystem::permissions: Operation not permitted: "/our/product/config.json"
A non-root user is not allowed to change the permission of a file owned by another user, not mention that this configuration file is created by root and owned by root.

A workaround for this is: set the permission to 666 only when it's created. Something like this:
    bool flag = isConfigFileExist(...)  
    pt::write_json(...)
    if (!flag) {
        changePermission(666)
    }

Monday, June 5, 2017

indent with 4 spaces in Emacs json-mode

1. install json-mode with
M-x package-install RET json-mode RET

2. set indent with:
M-x customize-group RET json-mode RET
Then change the default number from '2' to '4'.

Thursday, May 18, 2017

Rules for user-facing text

1. Do not use 'Please' in user-facing text
2. Do not use contractions in user-facing text. e.g. Change "won't be" to "is not". 

Monday, May 15, 2017

Modify port number in .xml configuration file

1234

[root@sandbox jetty]# cat a.sh
#!/bin/bash
port=$1

sed -i 's/[0-9]\+<\/Set>/'"${port}"'<\/Set>/g' jetty.xml


Example:
[root@sandbox jetty]# ./a.sh 5678

Friday, May 12, 2017

How to make an Ambari service support https only

I have already set up a new Ambari Service MyDemo which provides a quick link supporting http only. Here is the quicklink.json for it:


{
 "name": "default",
 "description": "default quick links configuration",
 "configuration": {
  "protocol": {
   "type": "http_only",
  },

  "links": [
   {
    "name": "mydemo_ui",
    "label": "MyDemo UI",
    "requires_user_name": "false",
    "component_name": "MYDEMO_SERVER",
    "url": "%@://%@:%@",
    "port":{
     "http_property": "mydemo.http.port",
     "http_default_port": "18042",
     "regex": "^(\\d+)$",
     "site":"mydemo-site"
    }
   }
  ]
 }
}

The quick link now points to http://sandbox.hortonworks.com:18042

Next, there is new request to make MyDemo support https only. I think the change should be quite straightforward - just replace all "http" in the configuration file with "https". But, a big BUT here, it does NOT work as expected. the quick link points to:
    http://sandbox.hortonworks.com
The protocol is incorrect and the port number is missing.

Based on the documentation from Ambari:
    https://cwiki.apache.org/confluence/display/AMBARI/Quick+Links
The protocol type can be "https_only" if the 'checks' are empty. But it just dose not work.

After several trials, here is the working version:


{
 "name": "default",
 "description": "default quick links configuration",
 "configuration": {
  "protocol": {
   "type": "https",
   "checks":[
    {
     "site":"mydemo-site"
    }
   ]
  },

  "links": [
   {
    "name": "mydemo_ui",    "label": "MYDEMO UI",
    "requires_user_name": "false",
    "component_name": "MYDEMO_SERVER",
    "url": "%@://%@:%@",
    "port":{
     "https_property": "mydemo.https.port",
     "https_default_port": "18043",
     "regex": "^(\\d+)$",
     "site":"mydemo-site"
    }
   }
  ]
 }
}

Note that the major change is to add the "checks" with only 'site' which is always true.
Now the quick link is pointing to https://sandbox.hortonworks.com:18043

No bug is NOT fixed eventually!


BTW:  Service log directory: /var/lib/ambari-agent/data

Monday, May 8, 2017

Configure embedded Jetty server with one .xml configuration file

String jettyConfig = "/tmp/jetty/keystore/jetty.xml";
XmlConfiguration configuration = new XmlConfiguration(new FileInputStream(jettyConfig)) ;
configuration.configure(server);

Embedded Jetty server to support https - Server Parameters in .XML configuration files

1. Java Code to start up Jetty Server:
        // load jetty xml files in order: jetty.xml -> jetty-ssl.xml -> jetty-ssl-context.xml -> jetty-https.xml
        List<String> configurations = new ArrayList<String>();
        configurations.add("jetty.xml");
        configurations.add("jetty-ssl.xml");
        configurations.add("jetty-ssl-context.xml");
        configurations.add("jetty-https.xml");


        String jettyConfigDir = "/myconfig/jetty/";
        XmlConfiguration last = null;
        List<Object> configuredObjects  = new ArrayList<Object>();
        for (String configFile : configurations) {
            InputStream configStream = null;

            File xmlConfiguration = new File(jettyConfigDir + configFile);
            if (xmlConfiguration.exists()) {
                configStream = new FileInputStream(xmlConfiguration);
            } else {

            }

            XmlConfiguration configuration = new XmlConfiguration(configStream);
            if (last != null) {
                configuration.getIdMap().putAll(last.getIdMap());
            }
            configuredObjects.add(configuration.configure());
            last = configuration;
        }

        // first object is a Server instance because of the jetty.xml
        Server server = (Server) configuredObjects.get(0);

2. jetty.xml
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">

<!-- =============================================================== -->
<!-- Documentation of this file format can be found at:              -->
<!-- http://wiki.eclipse.org/Jetty/Reference/jetty.xml_syntax        -->
<!-- =============================================================== -->

<!-- =============================================================== -->
<!-- Configure a Jetty Server instance with an ID "Server"           -->
<!-- Other configuration files may also configure the "Server"       -->
<!-- ID, in which case they are adding configuration to the same     -->
<!-- instance.  If other configuration have a different ID, they     -->
<!-- will create and configure another instance of Jetty.            -->
<!-- Consult the javadoc of o.e.j.server.Server for all              -->
<!-- configuration that may be set here.                             -->
<!-- =============================================================== -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
 <!-- =========================================================== -->
    <!-- extra server options                                        -->
    <!-- =========================================================== -->
    <Set name="stopAtShutdown"><Property name="jetty.server.stopAtShutdown" default="true"/></Set>
    <Set name="stopTimeout"><Property name="jetty.server.stopTimeout" default="5000"/></Set>
    <Set name="dumpAfterStart"><Property name="jetty.server.dumpAfterStart" deprecated="jetty.dump.start" default="false"/></Set>
    <Set name="dumpBeforeStop"><Property name="jetty.server.dumpBeforeStop" deprecated="jetty.dump.stop" default="false"/></Set>

    <New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
      <Set name="secureScheme">https</Set>
      <Set name="securePort"><Property name="jetty.ssl.port" default="1234" /></Set>
      <Set name="outputBufferSize">32768</Set>
    </New>

</Configure>
3. jetty-ssl.xml
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">

<!-- ============================================================= -->
<!-- Base SSL configuration                                        -->
<!-- This configuration needs to be used together with 1 or more   -->
<!-- of jetty-https.xml or jetty-http2.xml                         -->
<!-- ============================================================= -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
  <New id="sslHttpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
    <Arg><Ref refid="httpConfig"/></Arg>
    <Call name="addCustomizer">
      <Arg><New class="org.eclipse.jetty.server.SecureRequestCustomizer"/></Arg>
    </Call>
  </New>

  <!-- =========================================================== -->
  <!-- Add a SSL Connector with no protocol factories              -->
  <!-- =========================================================== -->
  <Call  name="addConnector">
    <Arg>
      <New id="sslConnector" class="org.eclipse.jetty.server.ServerConnector">
        <Arg name="server"><Ref refid="Server" /></Arg>
        <Arg name="factories">
          <Array type="org.eclipse.jetty.server.ConnectionFactory">
          </Array>
        </Arg>
        <Set name="host"><Property name="jetty.ssl.host" deprecated="jetty.host" /></Set>
        <Set name="port"><Property name="jetty.ssl.port" deprecated="ssl.port" default="1234" /></Set>
        <Set name="idleTimeout"><Property name="jetty.ssl.idleTimeout" deprecated="ssl.timeout" default="30000"/></Set>
      </New>
    </Arg>
  </Call>
</Configure>
4. jetty-ssl-context.xml
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">

<!-- ============================================================= -->
<!-- SSL ContextFactory configuration                              -->
<!-- ============================================================= -->

<!--
  To configure Includes / Excludes for Cipher Suites or Protocols see tweak-ssl.xml example at
     https://www.eclipse.org/jetty/documentation/current/configuring-ssl.html#configuring-sslcontextfactory-cipherSuites
-->

<Configure id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory">
 <Set name="KeyStorePath">
   <Property name="jetty.base" default="." />/<Property name="jetty.sslContext.keyStorePath" deprecated="jetty.keystore" default="../config/\
jetty/jetty.keystore"/></Set>
  <Set name="KeyStorePassword"><Property name="jetty.sslContext.keyStorePassword" deprecated="jetty.keystore.password" default="OBF:1sot1v96\
1saj1v9i1v941sar1v9g1sox"/></Set>

</Configure>
5. jetty-https.xml
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">

<!-- ============================================================= -->
<!-- Configure a HTTPS connector.                                  -->
<!-- This configuration must be used in conjunction with jetty.xml -->
<!-- and jetty-ssl.xml.                                            -->
<!-- ============================================================= -->
<Configure id="sslConnector" class="org.eclipse.jetty.server.ServerConnector">
  <Call name="addIfAbsentConnectionFactory">
    <Arg>
      <New class="org.eclipse.jetty.server.SslConnectionFactory">
        <Arg name="next">http/1.1</Arg>
        <Arg name="sslContextFactory"><Ref refid="sslContextFactory"/></Arg>
      </New>
    </Arg>
  </Call>

  <Call name="addConnectionFactory">
    <Arg>
      <New class="org.eclipse.jetty.server.HttpConnectionFactory">
        <Arg name="config"><Ref refid="sslHttpConfig" /></Arg>
        <Arg name="compliance"><Call class="org.eclipse.jetty.http.HttpCompliance" name="valueOf"><Arg><Property name="jetty.http.compliance\
" default="RFC7230"/></Arg></Call></Arg>
      </New>
    </Arg>
  </Call>
</Configure>

Embedded Jetty server to support https - hard coded Server Parameters

/*
         Create a basic jetty server object without declaring the port. Since
         we are configuring connectors directly we'll be setting ports on
         those connectors.
        */
        Server server = new Server();
        // gracefully shutdown
        server.setStopAtShutdown(true);

        /*
          SSL Context Factory for HTTPS
          SSL requires a certificate so we configure a factory for ssl contents
          with information pointing to what keystore the ssl connection needs
          to know about. Much more configuration is available the ssl context,
          including things like choosing the particular certificate out of a
          keystore to be used.
        */
        SslContextFactory sslContextFactory = new SslContextFactory();
        sslContextFactory.setKeyStorePath(keystoreFile.getAbsolutePath());
        // Fixed me: password as incoming parameter
        sslContextFactory.setKeyStorePassword("OBF:1sot1v961saj1v9i1v941sar1v9g1sox");

/*
          HTTPS Configuration
          HttpConfiguration is a collection of configuration information
          appropriate for http and https. The default scheme for http is
          <code>http</code> of course, as the default for secured http is
          <code>https</code> but we show setting the scheme to show it can be
          done. The port for secured communication is also set here.
          On this HttpConfiguration object we add a SecureRequestCustomizer
          which is how a new connector is able to resolve the https connection
          before handing control over to the Jetty Server.
        */
        HttpConfiguration https_config = new HttpConfiguration();
        https_config.setSecureScheme("https");
        https_config.setSecurePort(port);
        https_config.setOutputBufferSize(32768);

        SecureRequestCustomizer src = new SecureRequestCustomizer();
        src.setStsMaxAge(2000);
        src.setStsIncludeSubDomains(true);
        https_config.addCustomizer(src);

        /*
          HTTPS connector
          We create a second ServerConnector, passing in the http configuration
          we just made along with the previously created ssl context factory.
          Next we set the port and a longer idle timeout.
        */
        ServerConnector https = new ServerConnector(server,
                                                    new SslConnectionFactory(sslContextFactory,HttpVersion.HTTP_1_1.asString()),
                                                    new HttpConnectionFactory(https_config));
        https.setPort(port);
        https.setIdleTimeout(500000);

        // Add HTTPS connector to server
        server.addConnector(https);

Tuesday, April 4, 2017

how to use const vars in AngularJS

1. define const with .constant

 angular.module('myapp').constant("CONST", {
     "URL" : "www.google.com",
     "WELCOME_MSG": "Hello world",
     "PI" : 3.1415926
  }); 

2. Reference consts with:
angular.module('myapp').controller('myCtrl', ['$scope', '$rootScope', '$log', 'CONST', function($scope, $rootScope, $log, CONST) {
     $log.info("URL is", CONST.URL);
 }]);

Monday, March 6, 2017

$http to call REST APIs in Angularjs

Examples:
1. GET
            var successCallback = function(response) {
                $scope.kerberos = response.data.Kerberos;
                if ($scope.kerberos == "disabled") {
                    $log.info('kerberos is disabled.');
                } else {
                    $log.info('kerberos is enbaled.');
                }
            };

            var errorCallback = function(response) {
                $scope.error = response.data;
            };

            $http({
                method: 'GET',
                url: '/api/v1.0/configuration/kerberos'
            })
                .then(successCallback, errorCallback);

2. POST
            $scope.addDevice = function($event) {
                if($scope.addDevice.password != $scope.addDevice.confirmPassword) {
                    alert("Passwords Don't Match");
                    return false;
                }

                var successCallback4addDevice = function(response) {
                    $log.info('Device', response.data.id);
                    eventBus.emit('backup:adddevice:off', response);
                };

                var errorCallback4addDevice = function(response) {
                    eventBus.emit('backup:adddevice:off', response);
                };

                var dataobj = {
                        username: $scope.addDevice.user,
                        hostname: $scope.addDevice.server,
                        path: $scope.addDevice.storage
                };
                if ($scope.kerberos == "disabled") {
                    $log.info('create password obj');
                    dataobj.password = $scope.addDevice.password;
                } else {
                    $log.info('create kerberoscc obj');
                    dataobj.kerberoscc = $scope.addDevice.kerberoscc;
                }

                eventBus.emit('backup:adddevice:on');
                $http({
                    method: 'POST',
                    url: '/api/v1.0/configuration/backup-devices',
                    data: dataobj
                })
                    .then(successCallback4addDevice, errorCallback4addDevice);

            };

Friday, February 24, 2017

angularjs - access value of ng-model in a controller

To access the value of ng-model in a controller, you have to have a dot in there.
With a format like object.property you'll be good to go.

In my case "add.device.storage" does not work. And  "addDevice.storage" is good.

In view(.html):

<input type="text" id="input-id-dd-password" ng-model="addDevice.password"
    placeholder="type here">

In controller(.js): access it with $scope.addDevice.password

Thursday, February 16, 2017

java cmd cheatsheet

1. List files in a jar package:
 $ jar tvf my.jar

2. Extract files out of a jar package:
 $ jar xvf my.jar

3. Package current directory with Manifest file:
 $ jar cvfm my.jar META-INF/MANIFEST.MF ./

 4. javap is like nm in *NIX

5. jps like ps in *NIX
    jps -lvm

6. Print flags of a JVM process
    jinfo -flags

7. jconsole, other than jps/jinfo commands you can use jconsole to monitor a JVM process. It provides lots of information you need to tune your process.

8. jvisualvm, similar as jconsole

9. jstack, print process stack information

Wednesday, February 15, 2017

Adding getter/setter for Java class members

"Source" -> "Generate Getters and Setters".

Wednesday, January 25, 2017

boost ptree

This is an awesome post on how to use ptree for json processing. http://zenol.fr/blog/boost-property-tree/en.html

Thursday, January 12, 2017

JSON in Java

Add to your Maven dependency
1
2
3
4
5
<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.json</artifactId>
    <version>1.0.4</version>
</dependency>
Demo:
1
2
3
4
5
6
7
String json = "{\"id\":3}";
JsonReader reader = Json.createReader(new StringReader(json));
JsonObject rootObject = reader.readObject();
reader.close();

int devID = rootObject.getInt("id");
String sDevID = Integer.toString(devID);