hide's memo
30 Apr, 2024

KAWASAKI ninja250SL drive-sprocket and noise

[Japanese(日本語)]

Annoying noise

I bouht a second hand KAWASAKI ninja 250 SL  in December 2023. But I was annoyed by the strange noises which become bigger when I run 5th or 6th geer. I heard the sound of iron or something scraping.I bring my motorcycle to the shop but they said that it was no problem. I was not convinced, so I researched it on the internet and I got an information.  The drive sprocket which is not a genuine parts sometimes makes a wired noise, because of lacking a rubber which makes noise easy.

I opened the sprocket cover and noticed that the previous owner changed the drive sprocket to SUNSTAR 378. And the chain guide plate was scratched abnormally. The chain guide plate was set upside down. I guess the previous owner might made a mistake.

I thought the strange noise was come from this upside down chain guide plate. I tried to run without the chain guide plate, But it still made the strange noise. I guess the chain guide plate was already fully scratched not to make the noise.

SUNSTAR 378
scratched chain guide plate. In this picture, the chain guide plate was set upside down.
You can see the chain guide plate over the cover, If you set the guide correctly.

 

Changing the drive sprocket

I went to a motorcycle supplies store and ordered the genuine part(KAWASAKI 13144-0577) and have it changed.
that made the strange noise gone. ( additionally, the shop clerk scrape the chain guide plate to set normally)

Before the change: You can hear the strange noise. especially around 10th seconds.

After the change:  You can’t hear the strange noise.

24 Apr, 2023

apache + perl + cgi + mysql (DBD::mysql, DBI) on MacBook M1 using Docker

[Japanese(日本語)]

This article shows how to create apache,PerlCgi and mysql(DBD::mysql, DBI) on MacBook M1 using Docker as follows.

 

■1. Create a Docker container.

(1.1)Get Docker image.

docker image pull amd64/ubuntu:focal

(1.2)Create a Docker container.

docker run -p 8080:80 -p 3307:3306 -it -d --name ubuntu amd64/ubuntu:focal

 

■2. Create Docker environment.

(2.1)Login the Docker container.

docker exec -it ubuntu /bin/bash

(2.2)Install needed applications as follows.

apt update
apt install -y apache2
    You may be asked timezone, so answer properly.
apt install -y wget
apt install -y gcc
apt install -y make
apt install -y mysql-server
apt install -y libmysqlclient-dev
apt install libssl-dev
wget https://www.cpan.org/modules/by-module/DBI/DBI-1.643.tar.gz
tar xvzf DBI-1.643.tar.gz
cd DBI-1.643
perl Makefile.PL
make
make install
cpan update
cpan install DBD::mysql
a2enmod cgid

 

Add 2023/4/25

you might also be able to install DBI as follows.

cpan install DBI

instead of following steps.

wget https://www.cpan.org/modules/by-module/DBI/DBI-1.643.tar.gz
tar xvzf DBI-1.643.tar.gz
cd DBI-1.643
perl Makefile.PL
make
make install

 

■3. Create MySQL Database and input sample data.

(3.1)Create Database and user.

mysqld_safe --user=mysql &
mysql -u root
mysql>create database mydb;
mysql>create user 'test'@localhost identified by 'test';
mysql>grant all privileges on mydb.* to 'test'@localhost;
mysql>alter user 'test'@localhost IDENTIFIED WITH mysql_native_password by 'test';
mysql>quit

(3.2)Insert sample data.

mysql -u test -p
mysql>test
mysql>use mydb;
mysql>create table m_id(id varchar(30), name varchar(30));
mysql>insert into m_id values('001','admin'); 
mysql>insert into m_id values('002','Smith'); 
mysql>insert into m_id values('003','Johnson'); 
mysql>insert into m_id values('004','Williams'); 
mysql>commit;
mysql>quit

 

 

■4. Create sample perl CGI.

(4.1)Set perl CGI file as follows.

Path:/usr/lib/cgi-bin/test.cgi
Source:

#!/usr/bin/perl
use strict;
use DBI;

my $DB_HOST="127.0.0.1";
my $DB_PORT="3306";
my $DB_NAME="mydb";
my $DB_USER="test";
my $DB_PASS="test";

sub get_db_conn()
{
  my $dbh=undef;
  eval {
    $dbh = DBI->connect("dbi:mysql:dbname=$DB_NAME;host=$DB_HOST;port=$DB_PORT","$DB_USER","$DB_PASS");
  };
  if($@){
    print STDERR "DB ERROR $@n";
    $dbh = undef;
  }
  return $dbh;
}

my $dbh = get_db_conn();
my $sql = "select id, name from m_id";
my $sth = $dbh->prepare($sql);
$sth->execute();
print "Content-type: text/html;\n\n";
print "<html>";
print "<body>";
print "<table border=1>";
while(my $ary_ref = $sth->fetchrow_arrayref){
  my($id, $name) = @$ary_ref;
  print "<tr><td>$id</td><td>$name</td></tr>";
}
print "</table>";
print "</body>";
print "</html>";

 

■5. Confirmation

(5.1)start apache

apachectl start

(5.2)Access the following link.
http://localhost:8080/cgi-bin/test.cgi

19 Apr, 2023

SEIKO 4R35 position accuracy

[Japanese(日本語)]

I checked SEIKO SZSB011(4R35 movement)  gain/lose every 12 hours for 1o days with changing the position.

This watch gains between 6 sec and 10 sec per 24 hours.
and loses between 15 sec and 20 sec per 24 hours.

  position    gain/lose     gain/lose per 24 hours.
  crown right       -8      -16.02
  crown right      -8     -16.53
  flat lay      +5       +9.69
  flat lay      +4       +8.36
  flat lay      +3       +6.00
  flat lay      +3       +6.03
  flat lay      +4       +7.67
  crown right      -9      -17.83
  flat lay      +3      +6.13
  flat lay      +4      +8.23
  flat lay      +4      +8.06
  crown right      -8     -15.74
  flat lay      +5      +8.99
  flat lay      +3      +6.98
  flat lay      +5      +9.22
  crown right      -8     -17.12
  crown right      -8     -16.02
  flat lay      +3      +6.03
  flat lay      +5      +9.59
  flat lay      +5      +10.13
  crown right     -10     -20.37
  crown right      -8     -15.76

 

 

18 Apr, 2023

create a mesh polygons and set a texutre image on it using THREE.js (WebGL)

[Japanese(日本語)]

This is a sample of how to create a mesh polygons and set a texture image on it.

[demo]

(1)Polygons are consist of N x N positions.
(2)Create triangles using N x N positions. Specifying index number of positions.
(3)Set random values on position’s z axis to make surface bumpy.
(4)Set a texture on those triangles as below.

 

source code(html+javascript。you need THREE.js)
https://github.com/hidemiubiz/public/blob/main/Web/WebGL/sample02.html

 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<script src="three.js"></script>
<script type="text/javascript">
  window.addEventListener('DOMContentLoaded', init);

  const scene = new THREE.Scene();
  var rectangle;
  var renderer;
  var camera;

  function init() {
    const width = 600;
    const height = 400;

    renderer = new THREE.WebGLRenderer({
      canvas: document.querySelector('#myCanvas')
    });
    renderer.setSize(width, height);
    renderer.setPixelRatio(window.devicePixelRatio);

    camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000);
    camera.position.set(1.5, 1.0, 1.5);
    camera.lookAt(new THREE.Vector3(0, 0.5, 0));

    rectangle = createRectangleWithTexture(20, 1);
    scene.add(rectangle);

    const light = new THREE.DirectionalLight(0xFFFFFF, 1.0);
    light.position.set(1, 1, 1);
    scene.add(light);

    const ambientLight = new THREE.AmbientLight(0x222222);
    scene.add(ambientLight);

    requestAnimationFrame(render_scene);
  }

  function render_scene()
  {
    // 物体回転させる(Rotate object)
    rectangle.rotation.y += 0.01;

    renderer.render(scene, camera);
    requestAnimationFrame(render_scene);
  }

  function createRectangleWithTexture(NUM_MESH, length){
    // ポリゴンの頂点座標の配列(Polygon's positon array)
    var pos = new Float32Array(NUM_MESH*NUM_MESH*3);
    var n=0;
    for(var y=0; y<NUM_MESH; y++){ 
      for(var x=0; x<NUM_MESH; x++){
        pos[n] = x * length/NUM_MESH; n++;
        pos[n] = y * length/NUM_MESH; n++;
        pos[n] = Math.random()*(length/NUM_MESH); n++; // ランダム値をセット(Set random value)
      }
    }

    // ポリゴンの三角形をインデックスで指定(Polugon's index array)
    n=0;
    var index = new Uint32Array(3*((NUM_MESH-1)*(NUM_MESH-1)*2));
    for(var y=0; y<NUM_MESH-1; y++){ 
      for(var x=0; x<NUM_MESH-1; x++){
        index[n] = y*NUM_MESH + x; n++;
        index[n] = y*NUM_MESH + x + 1; n++;
        index[n] = (y+1)*NUM_MESH + x + 1; n++;

        index[n] = y*NUM_MESH + x; n++;
        index[n] = (y+1)*NUM_MESH + x + 1; n++;
        index[n] = (y+1)*NUM_MESH + x; n++;
      }
    }

    // ポリゴンのTexgure位置座標の配列 (Texture uv positions array)
    n=0;
    var uvs = new Float32Array(NUM_MESH*NUM_MESH*2);
    for(var y=0; y<NUM_MESH; y++){ 
      for(var x=0; x<NUM_MESH; x++){
        uvs[n] = x/(NUM_MESH-1); n++;
        uvs[n] = y/(NUM_MESH-1); n++;
      }
    }

    // 2つの三角形をインデックスで指定(Polygon's index array)
    const geom = new THREE.BufferGeometry();
    geom.setAttribute("position", new THREE.BufferAttribute(pos, 3));
    geom.setIndex(new THREE.BufferAttribute(index,1)); 
    geom.computeVertexNormals();
    geom.setAttribute("uv", new THREE.BufferAttribute(uvs, 2));

    const texture = new THREE.TextureLoader().load("webgl_texture01.png");

    const triMat = new THREE.MeshStandardMaterial({color:0xffffff, map: texture, side:THREE.DoubleSide});
    const triMesh = new THREE.Mesh(geom, triMat);
    return triMesh;
  }

</script>
</head>
<body>
<canvas id="myCanvas"></canvas>
</body>
</html>
17 Apr, 2023

Create simple polygons and set a texture image on it using THREE.js (WebGL)

[Japanese(日本語)]

This is a sample of how to create simple polygons and set a texutre image on it.

[demo]

(1)Polygons are consist of 4 positions.
(2)Create 2 triangles using 4 positions. Specifying index number of positions.

 

 

 

(3)Set a texture on 2 triangles as below.

 

source code(html+javascript。you need THREE.js)
https://github.com/hidemiubiz/public/blob/main/Web/WebGL/sample01.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<script src="three.js"></script>
<script type="text/javascript">
    window.addEventListener('DOMContentLoaded', init);

    const scene = new THREE.Scene();
    var rectangle;
    var renderer;
    var camera;

    function init() {
       const width = 600;
       const height = 400;

       renderer = new THREE.WebGLRenderer({
          canvas: document.querySelector('#myCanvas')
       });
       renderer.setSize(width, height);
       renderer.setPixelRatio(window.devicePixelRatio);

       camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000);
       camera.position.set(0, 0, 5);

       rectangle = createRectangleWithTexture();
       scene.add(rectangle);

       const light = new THREE.DirectionalLight(0xFFFFFF, 1.0);
       light.position.set(1, 1, 1);
       scene.add(light);

       const ambientLight = new THREE.AmbientLight(0x222222);
       scene.add(ambientLight);

       requestAnimationFrame(render_scene);
    }

    function render_scene()
    {
       // 物体回転させる(Rotate object)
       rectangle.rotation.y += 0.01;

       renderer.render(scene, camera);
       requestAnimationFrame(render_scene);
    }

    function createRectangleWithTexture(){
       // ポリゴンの頂点座標の配列(Polygon's positon array)
       const pos = new Float32Array([
          -1.0, -1.0, 0.0,
          1.0, -1.0, 0.0,
          1.0, 1.0, 0.0,
          -1.0, 1.0, 0.0
       ]);
       // 2つの三角形をインデックスで指定(Polygon's index array)
       const index = new Uint32Array([
          0,1,2, 0,2,3
       ]);

       // ポリゴンのTexgure位置座標の配列 (Texture uv positions array)
       var uvs = new Float32Array([
          0,0, 1,0, 1,1, 0,1
       ]);

       const geom = new THREE.BufferGeometry();
       geom.setAttribute("position", new THREE.BufferAttribute(pos, 3)); // ポリゴンの頂点を指定 (Set Polygon's posistion) 
       geom.setIndex(new THREE.BufferAttribute(index,1)); //ポリゴンの頂点の順番を指定(Set ordder of Polygon's position) 
       geom.computeVertexNormals(); // ポリゴンの法線を計算 (calculate polygon's normal)
       geom.setAttribute("uv", new THREE.BufferAttribute(uvs, 2)); // テクスチャの位置を指定(Set texture's UV position)

       const texture = new THREE.TextureLoader().load("webgl_texture01.png");

       const triMat = new THREE.MeshStandardMaterial({color:0xffffff, map: texture, side:THREE.DoubleSide});
       const triMesh = new THREE.Mesh(geom, triMat);
       return triMesh;
    }

</script>
</head>
<body>
<canvas id="myCanvas"></canvas>
</body>
</html>

 

15 Apr, 2023

If you can’t launch Docker Desktop after closing it.

[Japanese(日本語)]

My environment: M1 MacBook Air  Ventura 13.2.1

You might not be able to launch Docker Desktop from Launchpad after you close it using [x] Buton.

I guess that the Docker Desktop is still running when you close it using [x] button.

So, you might have to kill the process as follows.

(1)Search Docker Desktop process ID as folows.

ps -aef | grep -i docker | grep -i desktop | grep name
  501 19845 19811   0 10:13AM ??         0:06.63 /Applications/Docker.app/Contents/MacOS/Docker Desktop.app/Contents/MacOS/Docker Desktop --name=dashboard

(2)kill the process.

Warning!! all Docker related process are killed. So you have to launch Docker Desktop from launchpad  and start your individual docker container again.

 

13 Apr, 2023

How to create your own SAML IdP

[Japanese(日本語)]

How you do test your Web System’s Authentication, if it uses SAML Authentication?
You might want your own SAML IdP for test purpose.
This article shows how to create your own SAML IdP.

 

■1. Overview of your own SAML IdP environment.

Create an environment as below.

(1)Create WordPress that connect with your own IdP.
(2)Use miniOrange SAML 2.0 SSO Plugin for your WordPress.
(3)Use SimpleSAMLphp for your own IdP.
(4)Create those environment using Docker.
(miniOrange SAML 2.0 SSO Plugin for free creates new account automatically when your own Idp send the valid SAML Response)

 

■2. How to create the environment.

You can use archived file which contains needed files. (More on detail of these fiels later)

(1)download my-env.tgz from the link below.
https://github.com/hidemiubiz/public/blob/main/SAML/my-env.tgz
(2)Extrace my-env.tgz wherever you want to create.
(3)Create your own IdP.
(3.1)Create your own IdP using Docker Compose.

cd my-env/my-idp
docker-compose up -d

(3.2)Create public key and private key.

docker exec -it my-idp-php-1 /bin/bash
cd /var/www/html
/bin/sh prepare-env.sh

save my.crt’s content. you have to use this later.
(private key is placed in /var/www/html. this is just a demo. but you had better place this file in other folder.)

(4)Create WordPress.
(4.1)Create WordPress using Docker Compose.

cd my-env/my-wp
docker-compose up -d

(4.2)Install WordPress by following the instruction.
Access “http://localhost:8000/wp-admin” and follow the instruction to install your WordPress.
(You only have to choose the language and create 1 acccount.)

(4.3)Install SAML Plugin to your WordPress.
(4.3.1)access “http://localhost:8000/wp-admin” with using the acount that you created.
(4.3.2)Select Plugin -> New.
(4.3.3)Search “SAML” , install “SAML Single Sign On-SSO Login” and activate it.

(4.4)SAML Plugin setting .
(4.4.1)Select miniOrange SAML 2.0 SSO.
(4.4.2)Select “Service Provider Setup” tab and set parameters as follows.

Identity Provider Name: test
Idp Entity ID or Issuer: http://localhost:8080/
SAML Login URL: http://localhost:8080/mylogin.php
X.509 Certificate: 上記(3.2)でメモした公開鍵

(4.4.3)Test Configuration

 

■3. About my-env.tgz

my-env/
  |--my-idp/
  |   |--docker-compose.yml
  |   |--php/
  |   |     |--php.ini
  |   |     |--Dockerfile
  |   |
  |   |--nginx/
  |   |     |--nginx.conf
  |   |
  |   |--www/
  |       |--html/
  |           |--mysaml.php
  |           |--mylogin.php
  |           |--makecert.sh
  |
  |--my-wp/
      |--docker-compose.yml

 

・my-env/my-idp/docker-compose.yml

Docker-Compose setting for my SAML IdP.

version: '3'
services:
  nginx:
    image: nginx:latest
    ports:
      - 8080:80
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf
      - ./www/html:/var/www/html
    depends_on:
      - php

  php:
    build: ./php
    volumes:
      - ./www/html:/var/www/html

 

・my-env/my-idp/php/php.ini
date.timezone = "Asia/Tokyo"

 

・my-env/my-idp/www/html/makecet.sh

Shell script to create my SAML IdP’s public key an private key.

!/bin/sh
CN=my
PASSWORD=abcdefgxyz

SJ="/C=JP/ST=Tokyo/L=Minato-ku/O=hidemiu/OU=hidemiu/CN=$CN"
openssl genrsa -des3 -passout pass:${PASSWORD} -out ${CN}.key 2048
openssl rsa -passin pass:${PASSWORD} -in ${CN}.key -out ${CN}.key
openssl req -new -sha256 -key ${CN}.key -out ${CN}.csr -subj "$SJ"
openssl req -x509 -in ${CN}.csr -key ${CN}.key -out ${CN}.crt -days 3650

 

・my-env/my-idp/www/html/mylogin.php

https://github.com/hidemiubiz/public/blob/main/SAML/my-env/my-idp/www/html/mylogin.php

Receive SAMLRequest  from SP(WordPress). Hold the request and receive account Id that you want to login.

 

・my-env/my-idp/www/html/mysaml.php

https://github.com/hidemiubiz/public/blob/main/SAML/my-env/my-idp/www/html/mysaml.php

Create SAMLRequest with using Login Id and SAMLRequest, then go to SP(WordPress) login page.

 

・my-env/my-idp/php/Dockerfile
FROM php:7.2-fpm
COPY php.ini /usr/local/etc/php/
RUN docker-php-ext-install pdo_mysql

 

 

・my-wp/docker-compose.xml

Docker-compose setting for WordPress.

version: '3'

services:
  db:
    image: mysql:5.7
    platform: linux/amd64
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress

  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    ports:
      - "8000:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
volumes:
    db_data:

 

 

■4. SAML Authentication sequence of this environment.

9 Apr, 2023

How to get a refresh token from servicenow

[Japanese(日本語)]

How to get a refresh token from your servicenow instance with using OAuth2.0 Authorization code flow.

(1)Create endpoint on your servicenow.
(1.1)Login your servicenow instance.
(1.2)System OAuth -> Application Registory
(1.3)Push New button.
(1.4)Select “Create an OAuth API endopint for external clients”
(1.5)Apply your endpoint as below.

(2)Get Access code
(2.1)Open web browser
(2.2)Acccess the url below.


https://${YOUR_INSTANCE}.service-now.com/oauth_auth.do?response_type=code&redirect_uri=https%3A%2F%2Flocalhost%2Ftest&client_id=${YOUR_CLIENT_ID}&grant_type=authorization_code&state=123

* redirect_url ... https://localhost/test (you can apply the url that you specified on your endpoint.)
* state ... 123(you can apply your favorit word. this is just a sample)

 

(2.3)you can get login page.(if you don’t login your servicenow instance)


(2.4)Put “Allow” Button.


(2.5)Your redirect must be fail, but you can get the code on your address bar.


(2.6)save the code.

(3)Get Access token and Refresh token.
(3.1)prepare shell script as below.

#!/bin/sh

MY_INSTANCE="**** YOUR INSTANCE ****"
CLIENT_ID="**** YOUR CLIENT ID ****"
CLIENT_SECRET="**** YOUR CLIENT SECRET ****"
REDIRECT_URI="https%3A%2F%2Flocalhost%2Ftest" # you can apply the url that you specified on your endpoint.)
STATE="123" # specify the same word of (2.2)
CODE=$1

RESULT=`curl -X POST https://${MY_INSTANCE}.service-now.com/oauth_token.do -d "grant_type=authorization_code" -d "code=${CODE}" -d "redirect_uri=${REDIRECT_URI}" -d "client_id=${CLIENT_ID}"\
-d "client_secret=${CLIENT_SECRET}" -d "state=${STATE}"`

echo $RESULT

 

(3.2)exec the script above with argument of the code(sequence No.2.6)
(3.3)you can get the refresh token.

{“access_token”:”***********”,“refresh_token”:”*******”,”scope”:”useraccount”,”token_type”:”Bearer”,”expires_in”:1799}

 

■how to access servicenow REST-API with using Refresh token

seek the link below.

Get data from ServiceNow using curl

6 Apr, 2023

Fiddler

[Japanese(日本語)]

HTTP Packet capture tool.
you can see HTTP communications between your web browser and web server.
Additionally, you can change the HTTP request and response.

 

■How to see HTTP communications

(1)select the communication you want to see.
(2)select “Inspectors” tab.
(3)Select “Raw” tab.
(4)you can see HTTP request in the right upper window.
(5)you can see HTTP resonse in the right upper window.

 

 

■How to change HTTP request.

(1)Select Rules -> Automatic Breakpoints -> Before Request.
then Fiddler holds every HTTP request before sending.
(2)Choose holded HTTP communication.
(3)You can change HTTP request.
(4)Push Run to Completion Button.

As Fiddler holds every HTTP request,
You have to process every HTTP request .

■How to use Fiddler’s record to JMeter.

(1)Export Fiddler’s record as “cURL Script”.

(2)Import data to JMeter.

When you import the “cURL Script”. JMeter kindly prepare Cookie Manager which is basically required by Most Web Application.
Additionaly , you will have “View Result Tree”, So you can check the JMeter’s test result.

But, Thread Group is set with more than 10 thread.
I think you shuld better change Thred properties so that you can simply see how the test senario run.