HTTPプロキシサーバ: HTTPリクエストとレスポンスを中継するが、その際にHTTPリクエストの内容を記録してシナリオを作ることができる
Simple Controllerを追加

HTTP(S) Test Script Recorder

なかなか難しいな
随机应变 ABCD: Always Be Coding and … : хороший
HTTPプロキシサーバ: HTTPリクエストとレスポンスを中継するが、その際にHTTPリクエストの内容を記録してシナリオを作ることができる
Simple Controllerを追加

HTTP(S) Test Script Recorder

なかなか難しいな
Test Plan -> Add -> Thread(Users) -> Thread Group

HTTP Request
HTTP RequestのGet, ip, path, paramなどを設定する

Thread Group
Thread Propertiesの Threads(リクエスト数), Ramp-up period(リクエストの作成期間), Loop Count(リクエスト量)を設定する
Listenerの追加: テスト結果を表示
Summary Reportを追加

なるほど、一通りの機能はわかったが、複数画面はどうやるんだろうか?
ApacheBenchはApache HTTP Serverに同梱されている性能テストツール
単一のURLへのリクエストを生成するツール
$ ab -n 100 -c 10 http://google.com/
nオプション: 生成するリクエスト数
cオプション: 並列実行する数
$ ab -n 100 -c 10 http://google.com/
This is ApacheBench, Version 2.3 <$Revision: 1843412 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking google.com (be patient)…..done
Server Software: gws
Server Hostname: google.com
Server Port: 80
Document Path: /
Document Length: 219 bytes
Concurrency Level: 10
Time taken for tests: 1.533 seconds
Complete requests: 100
Failed requests: 0
Non-2xx responses: 100
Total transferred: 77300 bytes
HTML transferred: 21900 bytes
Requests per second: 65.23 [#/sec] (mean)
Time per request: 153.297 [ms] (mean)
Time per request: 15.330 [ms] (mean, across all concurrent requests)
Transfer rate: 49.24 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 1 2 3.0 1 13
Processing: 103 134 26.4 128 225
Waiting: 103 132 25.6 126 222
Total: 104 136 26.3 130 226
Percentage of the requests served within a certain time (ms)
50% 130
66% 134
75% 139
80% 142
90% 157
95% 217
98% 226
99% 226
100% 226 (longest request)
なるほど
$ tree
.
└── common
├── layer
│ └── python
│ └── util.py
└── serverless.yml
serverless.yml
service: sample-layer
provider:
name: aws
layers:
samplelayer:
path: layer
util.py
def hello():
print('Hello, Lambda Layers World!')
serverless.yml
service: sample-function
provider:
name: aws
runtime: python3.7
iamRoleStatements:
- Effect: "Allow"
Action:
- "lambda:InvokeFunction"
Resource: "*"
functions:
samplefunction:
handler: handler.handle_request
layers:
- {上記のLayerをsls deployした時に表示されるarn}
handler.py
import util def handler_request(event, context): util.hello()
Layerはデプロイされる度にバージョンが上がる
LayersのARNを確認
$ aws lambda list-layer-versions –layer-name sample-layer –query “LayerVersions[*].LayerVersionArn”
$ aws lambda update-function-configuration –function-name testFunction3 –layers “LayersのARN”
なるほど、なんとなく仕組みと概念は理解した
Lambdaレイヤーは追加のコード、データを含むことができる.zipアーカイブ
レイヤーには、ライブラリ、カスタムランタイム、データまたは設定ファイルを含めることができる
レイヤーを使用して共有のコードとの責任の分離を促進することで、ビジネスロジックの記述を迅速に繰り返すことができる
※lambdaでサードパーティライブラリを使うにはLqyerを使う必要がある
標準ライブラリで使える場合とそうでない時がある
from typing import Tuple import base64 from datetime import datetime, timedelta import hashlib import hmac import json import os import random import re import string import sys import time from typing import Any, Callable, Dict, List, Tuple import logging import jaconv import openai
関数の上にLqyersがattachされる
1つのLambda関数にattachできるレイヤーは最大5つまで
=> 2つ以上のライブラリを合体させたLqyerを作成
=> 圧縮されたzipファイルのサイズが50MBを超えないこと、展開後のファイルサイズが250MBを超えないこと
### Lambda Layerの作成手順
1. 開発環境を用意
2. 開発環境のPythonバージョンをLambdaと揃える
3. Lambda Layer用のディレクトリを作成
4. 必要なライブラリやモジュールをインストール
5. ディレクトリをZIPファイルに圧縮
6. LambdaコンソールからLambda Layerを作成
– 対象ディレクトリをZIPファイルに圧縮してダウンロード
– LambdaコンソールからLambda Layerを作成

Compatible architecturesに x86_64にチェックを入れる
Lambda LayerをLambda関数に追加する
Layersから呼び出すようにコードを修正する
import json
import logging
import config_rules_layer
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def check_ipv4Range_cidrs(inbound_permissions):
for permission in inbound_permissions:
logger.info(f'Permission: {permission}')
if not permission['userIdGroupPairs']:
for ipv4Range in permission['ipv4Ranges']:
logger.info(f'ipv4Range: {ipv4Range}')
if ipv4Range['cidrIp'] == '0.0.0.0/0':
logger.warning('Inbound rule includes risks for accessing from unspecified hosts.')
return ['NON_COMPLIANT', 'Inbound rule includes risks for accessing from unspecified hosts.']
return ['COMPLIANT', 'No Problem.']
else:
return ['COMPLIANT', 'No Problem.']
def evaluate_change_notification_compliance(configuration_item, rule_parameters):
try:
config_rules_layer.check_defined(configuration_item, 'configuration_item')
config_rules_layer.check_defined(configuration_item['configuration'], 'configuration_item[\'configuration\']')
config_rules_layer.check_defined(configuration_item['configuration']['ipPermissions'], 'ipPermissions')
inboundPermissions = configuration_item['configuration']['ipPermissions']
logger.info(f'InboundPermissions: {inboundPermissions}')
if rule_parameters:
config_rules_layer.check_defined(rule_parameters, 'rule_parameters')
if configuration_item['resourceType'] != 'AWS::EC2::SecurityGroup':
logger.info('Resource type is not AWS::EC2:SecurityGroup. This is ', configuration_item['resourceType'], '.')
return ['NOT_APPLICABLE', 'Resource type is not AWS::EC2:SecurityGroup.']
if inboundPermissions == []:
return ['COMPLIANT','Inbound rule does not have any permissions.']
else:
logger.info('check_ipv4Range_cidrs')
return check_ipv4Range_cidrs(inboundPermissions)
except KeyError as error:
logger.error(f'KeyError: {error} is not defined.')
return ['NOT_APPLICABLE', 'Cannot Evaluation because object is none.']
def lambda_handler(event, context):
global AWS_CONFIG_CLIENT
AWS_CONFIG_CLIENT = config_rules_layer.get_client('config', event)
invoking_event = json.loads(event['invokingEvent'])
logger.info(f'invoking_event: {invoking_event}')
rule_parameters = {}
if 'ruleParameters' in event:
rule_parameters = json.loads(event['ruleParameters'])
configuration_item = config_rules_layer.get_configuration_item(invoking_event)
logger.info(f'configuration_item: {configuration_item}')
compliance_type = 'NOT_APPLICABLE'
annotation = 'NOT_APPLICABLE.'
if config_rules_layer.is_applicable(configuration_item, event):
compliance_type, annotation = evaluate_change_notification_compliance(
configuration_item, rule_parameters
)
response = AWS_CONFIG_CLIENT.put_evaluations(
Evaluations=[
{
'ComplianceResourceType': invoking_event['configurationItem']['resourceType'],
'ComplianceResourceId': invoking_event['configurationItem']['resourceId'],
'ComplianceType': compliance_type,
'Annotation': annotation,
'OrderingTimestamp': invoking_event['configurationItem']['configurationItemCaptureTime']
},
],
ResultToken=event['resultToken']
)
<script>
function zenkaku2Hankaku(str){
return str.replace(/[A-Za-z0-9]/g, function(s){
return String.fromCharCode(s.charCodeAt(0) + 0xFEE0);
});
}
console.log(zenkaku2Hankaku("123abC"));
</script>
JSで書く場合も基本はスクリプトの中に辞書を持って変換しているのね。
仕組みを理解した。
mb_internal_encoding('utf-8');
$kana2romaji = new Kana2Romaji;
$str = "これは、ローマじへんかんのじっけんです";
$result = $kana2romaji->convert($str);
header("Content-type: text/html;charset=utf8");
echo $result;
class Kana2Romaji {
function convert($str){
$str = mb_convert_kana($str, "cHV", "utf-8");
$kana = array(
'きゃ', 'きぃ', 'きゅ', 'きぇ', 'きょ',
'ぎゃ', 'ぎぃ', 'ぎゅ', 'ぎぇ', 'ぎょ',
'くぁ', 'くぃ', 'くぅ', 'くぇ', 'くぉ',
'ぐぁ', 'ぐぃ', 'ぐぅ', 'ぐぇ', 'ぐぉ',
'しゃ', 'しぃ', 'しゅ', 'しぇ', 'しょ',
'じゃ', 'じぃ', 'じゅ', 'じぇ', 'じょ',
'ちゃ', 'ちぃ', 'ちゅ', 'ちぇ', 'ちょ',
'ぢゃ', 'ぢぃ', 'ぢゅ', 'ぢぇ', 'ぢょ',
'つぁ', 'つぃ', 'つぇ', 'つぉ',
'てゃ', 'てぃ', 'てゅ', 'てぇ', 'てょ',
'でゃ', 'でぃ', 'でぅ', 'でぇ', 'でょ',
'とぁ', 'とぃ', 'とぅ', 'とぇ', 'とぉ',
'にゃ', 'にぃ', 'にゅ', 'にぇ', 'にょ',
'ヴぁ', 'ヴぃ', 'ヴぇ', 'ヴぉ',
'ひゃ', 'ひぃ', 'ひゅ', 'ひぇ', 'ひょ',
'ふぁ', 'ふぃ', 'ふぇ', 'ふぉ',
'ふゃ', 'ふゅ', 'ふょ',
'びゃ', 'びぃ', 'びゅ', 'びぇ', 'びょ',
'ヴゃ', 'ヴぃ', 'ヴゅ', 'ヴぇ', 'ヴょ',
'ぴゃ', 'ぴぃ', 'ぴゅ', 'ぴぇ', 'ぴょ',
'みゃ', 'みぃ', 'みゅ', 'みぇ', 'みょ',
'りゃ', 'りぃ', 'りゅ', 'りぇ', 'りょ',
'うぃ', 'うぇ', 'いぇ'
);
$romaji = array(
'kya', 'kyi', 'kyu', 'kye', 'kyo',
'gya', 'gyi', 'gyu', 'gye', 'gyo',
'qwa', 'qwi', 'qwu', 'qwe', 'qwo',
'gwa', 'gwi', 'gwu', 'gwe', 'gwo',
'sya', 'syi', 'syu', 'sye', 'syo',
'ja', 'jyi', 'ju', 'je', 'jo',
'cha', 'cyi', 'chu', 'che', 'cho',
'dya', 'dyi', 'dyu', 'dye', 'dyo',
'tsa', 'tsi', 'tse', 'tso',
'tha', 'ti', 'thu', 'the', 'tho',
'dha', 'di', 'dhu', 'dhe', 'dho',
'twa', 'twi', 'twu', 'twe', 'two',
'nya', 'nyi', 'nyu', 'nye', 'nyo',
'va', 'vi', 've', 'vo',
'hya', 'hyi', 'hyu', 'hye', 'hyo',
'fa', 'fi', 'fe', 'fo',
'fya', 'fyu', 'fyo',
'bya', 'byi', 'byu', 'bye', 'byo',
'vya', 'vyi', 'vyu', 'vye', 'vyo',
'pya', 'pyi', 'pyu', 'pye', 'pyo',
'mya', 'myi', 'myu', 'mye', 'myo',
'rya', 'ryi', 'ryu', 'rye', 'ryo',
'wi', 'we', 'ye'
);
$str = $this->kana_replace($str, $kana, $romaji);
$kana = array(
'あ', 'い', 'う', 'え', 'お',
'か', 'き', 'く', 'け', 'こ',
'さ', 'し', 'す', 'せ', 'そ',
'た', 'ち', 'つ', 'て', 'と',
'な', 'に', 'ぬ', 'ね', 'の',
'は', 'ひ', 'ふ', 'へ', 'ほ',
'ま', 'み', 'む', 'め', 'も',
'や', 'ゆ', 'よ',
'ら', 'り', 'る', 'れ', 'ろ',
'わ', 'ゐ', 'ゑ', 'を', 'ん',
'が', 'ぎ', 'ぐ', 'げ', 'ご',
'ざ', 'じ', 'ず', 'ぜ', 'ぞ',
'だ', 'ぢ', 'づ', 'で', 'ど',
'ば', 'び', 'ぶ', 'べ', 'ぼ',
'ぱ', 'ぴ', 'ぷ', 'ぺ', 'ぽ'
);
$romaji = array(
'a', 'i', 'u', 'e', 'o',
'ka', 'ki', 'ku', 'ke', 'ko',
'sa', 'shi', 'su', 'se', 'so',
'ta', 'chi', 'tsu', 'te', 'to',
'na', 'ni', 'nu', 'ne', 'no',
'ha', 'hi', 'fu', 'he', 'ho',
'ma', 'mi', 'mu', 'me', 'mo',
'ya', 'yu', 'yo',
'ra', 'ri', 'ru', 're', 'ro',
'wa', 'wyi', 'wye', 'wo', 'n',
'ga', 'gi', 'gu', 'ge', 'go',
'za', 'ji', 'zu', 'ze', 'zo',
'da', 'ji', 'du', 'de', 'do',
'ba', 'bi', 'bu', 'be', 'bo',
'pa', 'pi', 'pu', 'pe', 'po'
);
$str = $this->kana_replace($str, $kana, $romaji);
$str = preg_replace('/(っ$|っ[^a-z])/u', "xtu", $str);
$res = preg_match_all('/(っ)(.)/u', $str, $matches);
if(!empty($res)){
for($i=0;isset($matches[0][$i]);$i++){
if($matches[0][$i] == 'っc') $matches[2][$i] = 't';
$str = preg_replace('/' . $matches[1][$i] . '/u', $matches[2][$i], $str, 1);
}
}
$kana = array(
'ぁ', 'ぃ', 'ぅ', 'ぇ', 'ぉ',
'ヵ', 'ヶ', 'っ', 'ゃ', 'ゅ', 'ょ', 'ゎ', '、', '。', ' '
);
$romaji = array(
'a', 'i', 'u', 'e', 'o',
'ka', 'ke', 'xtu', 'xya', 'xyu', 'xyo', 'xwa', ', ', '.', ' '
);
$str = $this->kana_replace($str, $kana, $romaji);
$str = preg_replace('/^ー|[^a-z]ー/u', '', $str);
$res = preg_match_all('/(.)(ー)/u', $str, $matches);
if($res){
for($i=0;isset($matches[0][$i]);$i++){
if( $matches[1][$i] == "a" ){ $replace = 'â'; }
else if( $matches[1][$i] == "i" ){ $replace = 'î'; }
else if( $matches[1][$i] == "u" ){ $replace = 'û'; }
else if( $matches[1][$i] == "e" ){ $replace = 'ê'; }
else if( $matches[1][$i] == "o" ){ $replace = 'ô'; }
else { $replace = ""; }
$str = preg_replace('/' . $matches[0][$i] . '/u', $replace, $str, 1);
}
}
return $str;
}
function kana_replace($str, $kana, $romaji){
$patterns = array();
foreach($kana as $value){
$patterns[] = "/" . $value . "/";
}
$str = preg_replace($patterns, $romaji, $str);
return $str;
}
}
なるほど、プログラムの中に辞書を作っておいて、変換してる訳ね。
ini_set('display_errors', "On");
function seireki($wareki_year){
$wareki_year = str_replace("元年", "1年", mb_convert_kana($wareki_year, "n"));
if(preg_match('!^(明治|大正|昭和|平成|令和)([0-9]+)年$!', $wareki_year, $matches)){
$era_name = $matches[1];
$year = intval($matches[2]);
if($era_name === "明治"){
$year += 1867;
} else if($era_name === "大正"){
$year += 1911;
} else if($era_name === "昭和"){
$year += 1925;
} else if($era_name === "平成"){
$year += 1988;
} else if($era_name === "令和"){
$year += 2018;
}
return $year . "年";
}
return null;
}
echo seireki("平成元年");
$ php index.php
1989年
preg_matchで元号と年を分割する訳ね。なるほど、ロジックはわかった。
ini_set('display_errors', "On");
function wareki($year){
$eras = array(
array('year' => 2018, "name" => "令和"),
array('year' => 1988, "name" => "平成"),
array('year' => 1925, "name" => "昭和"),
array('year' => 1911, "name" => "大正"),
array('year' => 1867, "name" => "明治")
);
foreach($eras as $era){
$base_year = $era['year'];
$era_name = $era['name'];
if($year > $base_year){
$era_year = $year - $base_year;
if($era_year === 1){
return $era_name . "元年";
}
return $era_name . $era_year ."年";
}
}
return null;
}
echo wareki(1989);
$ php index.php
平成元
なるほど、これは凄い
$num = 100000; echo number_format($num);
$ php index.php
100,000
カンマ除去
$num = "100,000";
echo str_replace(",", "", $num);
$ php index.php
100000
半角カナ→全角カナ
$str = "キャピタルメディア"; echo mb_convert_kana($str, "KV");
$ php index.php
キャピタルメディア
全角カナ→半角カナ
$str = "キャピタルメディア"; echo mb_convert_kana($str, "kV");
$ php index.php
キャピタルメディアva
カナ以外にも、数字、英字、スペースも変換できる。なるほど。
日付変換
$date = "20230321";
echo date("Y/m/d", strtotime($date));
php index.php
2023/03/21
$date = "20230321";
echo date("Y年m月d日", strtotime($date));
$ php index.php
2023年03月21日