信頼はずっと、挑戦はもっと。

お問い合わせ
TEL:03-3496-3888

BLOG コアテックの社員ブログ (毎週月曜~金曜更新中)

LIST OF ARTICLES

記事一覧

  • テクログ

    Lambdaを試してみました

    お久しぶりです。在宅勤務になり、時間に余裕ができたのでAWSを色々試していました。今回はLambdaについて紹介したいと思います。処理の内容はS3のimagesにjpgの画像をアップすると、別のバケットにリサイズされた画像がアップされ、画像のアップロードパスと登録日時がdynamoDBに登録されます。まず、Lambda上でPillowを使えるようにするために、EC2で下記を実行しました。sudo yum -y install gcc openssl-devel bzip2-devel libffi-devel wget https://www.python.org/ftp/python/3.8.1/Python-3.8.1.tgz tar xzf Python-3.8.1.tgz cd Python-3.8.1 sudo ./configure --enable-optimizations sudo make altinstall pip3.8 install pillow -t . 上記で作成されたPILとPillow.libsとPillow-7.1.2.dist-infoとlambda_function.pyをzipで固めてアップロードします。次にLambdaのトリガーの設定ですが、S3を選択し、下記内容を入力し、追加をクリックします。バケット sample イベントタイプ すべてのオブジェクト作成イベント プレフィックス-オプション images/ サフィックス-オプション .jpg トリガーの有効化 チェック 次にdynamoDBで画像管理テーブルとautoincrementがないためidを管理するテーブルを作成します。テーブルを作成後、idsテーブルにtable_nameがs3_images、idが0を登録します。・s3_images id 主キー   数値型 upload_path 文字列型 created_at  文字列型 ・ids table_name 主キー 文字列型 id                数値型 次にS3で下記の二つのバケットを作成します。sample sample-resize 最後にlambda_function.pyは下記の内容です。import boto3 import os import sys import uuid from urllib.parse import unquote_plus from PIL import Image import PIL.Image import datetime s3_client = boto3.client('s3') dynamodb = boto3.resource('dynamodb') def resize_image(image_path, resized_path):   with Image.open(image_path) as image:     image.thumbnail(tuple(x / 2 for x in image.size))     image.save(resized_path) def get_id(table_name):   table = dynamodb.Table('ids')   data = table.update_item(     Key = {       'table_name': table_name     },     UpdateExpression = 'ADD id :id_val',     ExpressionAttributeValues = {       ':id_val': 1     },     ReturnValues = "UPDATED_NEW"   )       res = table.get_item(     Key = {       'table_name': table_name     }   )   return res['Item']['id'] def insert_dynamodb(id, upload_path):   table= dynamodb.Table('s3_images')   now = datetime.datetime.now()   table.put_item(     Item = {       'id': id,       'upload_path': upload_path,       'created_at': now.strftime("%Y-%m-%d %H:%M:%S")     }   ) def lambda_handler(event, context):   for record in event['Records']:     bucket = record['s3']['bucket']['name']     key = unquote_plus(record['s3']['object']['key'])     tmpkey = key.replace('/', '')     download_path = '/tmp/{}{}'.format(uuid.uuid4(), tmpkey)     upload_path = '/tmp/resized-{}'.format(tmpkey)     s3_client.download_file(bucket, key, download_path)     resize_image(download_path, upload_path)     s3_client.upload_file(upload_path, '{}-resized'.format(bucket), key)           id = get_id('s3_images')     insert_dynamodb(id, upload_path) これでS3のsampleバケットのimagesにjpgの画像をアップすると、sample-resizeバケットにリサイズされた画像がアップされます。Lambdaの設定は一部割愛しましたが、以上となります。
  • 画像:ブログサムネイル

    テクログ

    UIデザインのススメ

    マークアップエンジニアのひこです。たまにデザインを作ったりもするのですが、最近特にグラフィックデザインとUIデザインの違いみたいなものを感じています。かっこいいデザイン、きれいなデザイン、使いやすいデザイン・・・色々ありますが最終的には「サイトの目的達成」が一番重要かとおもいます。「商品を買ってもらう」「問合せしてもらう」「会員登録してもらう」などなど・・・。目的がわかると何を重視すればいいかがわかってくるので、ビジュアルを優先するのか操作感を優先するのかetc・・・。ビジュアルを優先する時はターゲットの性別・年齢・タイプなどを決め、対象者に人気のある類似サービスなどからヒントを得られますが、操作感を優先するとなるとどうすれば操作感が良くなるかがなかなかわかりません。そんな状態だったので勉強の為に本を1冊買ってきました。D.A.ノーマン著 誰のためのデザイン?結構分厚くて専門用語も出てくるので、読むのにかなりのカロリーを必要としました。が、これを読むと「なぜこのデザインは使いにくいのか」を言語化することができるようになってきます。まだ1回しか読んでいないので理解度もまだまだですが、リピートして完全に理解できるようになりたいと思えるいい本でした。オススメです!
  • テクログ

    git clone 時に出た 「the remote end hung up unexpectedly」に辛勝した話

    どうも!エンジニア歴2年目に突入したわいです。連投になって申し訳ないんですけど、先日ハマった沼から抜け出すために苦悩したことを備忘録として書き留めます。ウダウダ書いていますが、結果だけ知りたい方はまとめまで読み飛ばしてください。何が起きたか開発環境を CodeCommit から git clone したときに、下記のエラーに阻まれた。(いろいろあって開発環境を消してしまった…)FATAL ERROR: Remote side unexpectedly closed network connection fatal: the remote end hung up unexpectedly fatal: early EOF fatal: index-pack failed 1行目のエラーメッセージはなぜかコロコロ変わったりした。開発環境がないので、このままだと仕事ができないとかなり焦り、先輩に相談。>どうやら、リポジトリの容量がでかすぎるらしい試しに、先輩にもcloneし直してもらうと、、成功したあわよくばと思ったが、自力で解決するしかなくなった、、正直、Git Extensions のぬるま湯に1年間浸かりつづけていたので、Git が全くわかっていない。とりあえず、ガンガン試していく作戦に出た。何を試したかこれらの記事を参考にさせていただきました。ありがとうございます。https://stackoverflow.com/questions/6842687/the-remote-end-hung-up-unexpectedly-while-git-cloninghttps://cithukyaw.wordpress.com/2014/09/08/fix-for-the-fatal-error-early-eof-on-git-clone/https://qiita.com/cacahuatl/items/4d763e98f3934e3569ca① 「http.postBuffer」の設定を変更するgit config --global http.postBuffer 524288000 >結果は変わらなかったさらに2倍にしてみるgit config --global http.postBuffer 1048576000 >結果は変わらなかった② 「core.compression」を設定するhttps://git-scm.com/docs/git-configgit config --global core.compression 0 >結果は変わらなかった>設定値を -1, 9 と変えてみたが、結果は変わらなかった③  ssh接続のタイムアウトを設定する「Remote side unexpectedly closed network connection」で検索すると、sshのタイムアウトっぽいことが出てきたので試してみた~/.ssh/configServerAliveInterval 60 ServerAliveCountMax 3 >結果は変わらなかった④  一度にcloneする量を減らす(shallow clone)git clone --depth 1 <my_repo_URI> >結果は変わらなかったいくら調べても他の解決法が出てこないので、この時点でかなり詰んだと思った⑤  有線接続に変える在宅になってから、家の Wi-Fi で仕事をしていたことに先輩の一言で気づいたclone中の「MiB/s」が2倍近く増えたが、、>結果は変わらなかった>①~④のどれも結果は変わらなかった絶望の淵に立たされていたときに、一筋の光が差し込んだ⑥  masterブランチよりも軽いブランチをcloneするgit clone -b <smaller_branch> <my_repo_URI> >結果は変わらなかった一度にcloneする量を減らす(shallow clone)git clone -b <smaller_branch> --depth 1 <my_repo_URI> >clone成功!!現在、<smaller_branch>の最新のコミットだけ取得している状態なので、<smaller_branch>の全履歴を取得git fetch --unshallow >またもや、同様のエラーコミット数を制限して少しずつ履歴を取得git fetch --depth 8 # コミット数:8は任意 >fetch成功!!残りの履歴を取得git fetch --unshallow >fetch成功!!⑦  masterブランチを含め、他のブランチ情報を取得する.git/config の<smaller_branch>を * に変更する[remote "origin"]     url = <my_repo_URI>     fetch = +refs/heads/*:refs/remotes/origin/* git fetch >fetch成功!!これですべての履歴が取得できた>やっとの思いで、開発環境が復活!!まとめ結局、必要だったコマンド。git config --global http.postBuffer 524288000 git clone -b <smaller_branch> --depth 1 <my_repo_URI> git fetch --depth 8 git fetch --unshallow .git/config[remote "origin"]     url = <my_repo_URI>     fetch = +refs/heads/*:refs/remotes/origin/* git fetch 有線接続では以上のコマンドでcloneできた。Wi-Fi の場合、最後の git fetch だけがうまくいかなかった。>いきなり、* で fetch するのではなくて、別のブランチを一度 fetch して、再度 * で fetch したらいけたうーん、Gitムズイ、、そもそも、alpineでDocker環境を作ってたら、こんなことには、、他にいい方法があれば教えてください!以上、わいでした。健闘を祈る!!
  • 画像:ブログサムネイル

    テクログ

    オブジェクト指向は因数分解だ!!

    どうも!先月に入社二年目を迎え、とうとうパイセンと化したわいです。自粛期間中ということで、かなり暇なので長編に挑みます。暇な人はぜひ最後まで読んでみてください。「うわあ、暇だあ…」ってより実感すると思います。今回、またもやプログラミングを他の概念にこじつけるシリーズです。この一年間、新人プログラマーとしていろいろ苦戦しました。その中のひとつが、『オブジェクト指向とは』の理解です。オブジェクト指向に関する記事はたくさんあります。それこそ、「オブジェクト指向はもう古い」とされていたりします。ただ温故知新という言葉があるように、オブジェクト指向について学ぶことは決して意味のないことではないと思います。むしろ、プログラミングをする上での基本的な考え方が詰まっているように思えます。詳しく、そして正確に知りたい場合は、他の記事をおすすめします。https://www.google.com/search?q=%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E3%81%A8%E3%81%AF今回はオブジェクト指向のイメージを掴むために少しでもお役に立てればと思い、あえて変な角度からアプローチしてみます。その名も、「オブジェクト指向は因数分解だ!!」です。因数分解とは、「足し算・引き算で表されている数式をかけ算の形に変形する」ことです。例えば、cx^2+acx+bcx+abc = (x+a)(x+b)c となります。(中学数学でやりましたね?)ここで、下図のようなWebページについて考えてみましょう。(私自身、最初に車の例えを見たときピンとこなかったので…)犬の情報は、売られている犬がリストで表示されているとします。猫も同様です。店舗の情報は、住所、電話番号などが表示されているとしましょう。(ちなみに、私はペットショップに行くと悲しい気持ちになるので、基本的に中には入りません)かなり簡略化しているのでわかりやすいと思いますが、ペットショップのWebサイト = 犬の情報 × 猫の情報 × 店舗の情報という式が成り立つはずです。複雑なWebサイトでもこのように各パーツの組み合わせで成り立っています。これを先ほどの因数分解と合わせて考えてみます。ペットショップのWebサイト= cx^2+acx+bcx+abc (一見複雑だが…)=  (x+a)  ×  (x+b)  ×  c = 犬の情報 × 猫の情報 × 店舗の情報このようにWebサイトを因数分解することができました。「だから、なんだ?」という話なのですが、ここでオブジェクト指向について考えたいと思います。なぜわざわざ小難しいオブジェクト指向で書くかというと、それは変更に対して柔軟に対応するためです。どういうことかというと、「爬虫類も売ることにしたから、サイトに爬虫類の情報も表示したい」や、「犬を売るのをやめて、鳥を売ることにしたから変えてくれ」などという要望に、瞬時にそしてバグを出すことなく対応することがオブジェクト指向を用いると容易になるということです。適切にオブジェクト指向を使えば、似たような機能の追加が容易になり(再利用性)、たった一か所の変更のために他のパーツにバグが出ていないかページ全体をテストし直す必要がありません(疎結合性)。しかし、このオブジェクト指向の難しいところはどのように機能(クラス)を分割するかというところにあると思います。大雑把に分割しても効力は発揮しないし、かといって細かすぎても保守が大変になります。ここで、今回私が提案するのは「因数分解のように考えてみたら意外と上手くいくんじゃね?w」ってやつです。まず、「犬の情報」を「鳥の情報」に変えるということを因数分解で見てみましょう。これは、仮に a → d とすることで実現するとします。そうすると、ペットショップのWebサイト=  (x+d)  ×  (x+b)  ×  c = 鳥の情報 × 猫の情報 × 店舗の情報となり、(x+b)やc の値に何ら影響を与えることなく変更することが出来ました。ここで勘のいい人は、「おめえさん、x を変えたら『猫の情報 (x+b)』に影響を与えるだら?」と思うかもしれません。そうです。そして、この x がオブジェクト指向の要です。「犬の情報」も「猫の情報」も、『売られている動物がリストで表示される』という共通点があります。この共通点を規格として、インターフェースや抽象クラスにまとめ上げることで再利用性が高まり、さらに各々のクラスの役割がはっきりします。そして、ここで注意しないといけないのがなんでもかんでもこの x にまとめてしまうことです。各ペットの情報欄に年齢や性別のほかに、仮に「1日に〇回散歩に行かないといけない」という項目があったとします。これを x にまとめてしまうと『犬の情報 (x+a)』ではいいんですが、関係のない『猫の情報 (x+b)』に影響を与えてしまいます。だから、この場合は各ペットの情報欄の項目までは共通化せず、『売られている動物がリストで表示される』という根本機能だけを共通化することがいいように思えます。(犬と猫だけだと差異がわかりにくいですが、変わった動物を追加するとなると変な項目も増えそうです)かといって、ペットショップのWebサイトということなので、『売られている動物がリストで表示される』という機能の共通化を疑う必要はないでしょう。それだと、オブジェクト指向の意味がなくなります。次に、f(a) = x+a とすると、ペットショップのWebサイト=  f(a)  ×  f(b)  ×  c = 犬の情報 × 猫の情報 × 店舗の情報となり、 犬(a)  や  猫(b)  を f に与えるだけで欲しい情報が得られるということです。この f こそが、『売られている動物をリストで表示する』という機能であり、インターフェースです。この『動物』という抽象に対してプログラミングしていくことが、ポリモーフィズムです。最後に、カプセル化について考えます。f はインターフェースや抽象クラスで、 f(a) は『売られている犬をリストで表示する』という具象クラスです。実際にペットショップのWebサイトを構築する際は、この f(a) を使います。そして、この f(a) を利用するとき、『売られている犬をリストで表示する』という具象クラスであるということだけを知っていればよくて、f(a) = x+a だという具体的な中身を知っている必要は全くありません。実は、『売られている犬を「人気順に」リストで表示する』ということをやっていて、中身が f(a) = 3x+1+a と多少複雑になっているかもしれません。ただ、このように具体的な中身を知らずとも、 f(a) を使えばWebサイトは構築できます。クラスを外部から利用するとき、 f(a) のような簡素な見た目で提供し、影響範囲をクラス内にとどめておくことをカプセル化といいます。いかがでしたか?「オブジェクト指向は因数分解だ!!」理論は。あなたのソース、c(x^2+ax+bx+ab) や x^2(1+a/x)(1+b/x)c になっていないでしょうか?「うわあ、暇だあ…」最後まで読んでくださり、私としてはうれしい限りですが、相当お暇なんですね。なにか自粛期間にできる趣味をお探しになることをお勧めします。以上、わいでした。健闘を祈る!!
  • 画像:ブログサムネイル

    テクログ

    serverless frameworkで API GatewayのプライベートAPIを作成したい!

    プライベートAPI、便利ですね。内部でいろいろやるだけなのに外に出したくないですし。プライベートAPIをAPIGatewayで建てる場合、手動での作成や、既存で建ててあるAPIGatewayにリソースを追加することも可能ですが、serverless frameworkでlambdaのデプロイと同時にAPI GatewayのプライベートAPIを作成したいですよね。なのでやってみました。全体的にはhttps://www.serverless.com/framework/docs/providers/aws/events/apigateway/やhttps://github.com/serverless/serverless/pull/5080にあるのですが、いろいろ摘んで探していかないといけないので書いておきます。serverless.ymlが、このようになります!最低限くらいの内容です。service: internal-apigateway-test provider:   name: aws   endpointType: private   resourcePolicy:     - Effect: Allow       Principal: '*'       Action: execute-api:Invoke       Resource: arn:aws:execute-api:ap-northeast-1:<AWS account ID>:* #リソースにしぼってもいいです       Condition:         StringEquals:           'aws:sourceVpce': vpce-<あらかじめ作成してあるVPC Endpoint です>   runtime: python3.8   region: ap-northeast-1   role: ${opt:role_str, "arn:aws:iam::<AWS account ID>:role/aaaa"} functions:   main:     handler: handler.lambda_handler     name:  internal-apigateway-test     description: "(sample)内部APIGateway+簡単なjsonを返すだけlambdaの作成"     memorySize: 128     timeout: 5     events:       - http:           path: /           method: get ではよいslsライフを!
  • テクログ

    素敵だら! Linux コマンド ~diff~

    こんにちはうなぎです。IT開発者にとって避けては通れない数ある Linux コマンドのうちから、厳選してご紹介する不定期コーナー“素敵だら! Linux コマンド”。緊急事態宣言中に紹介するのは「diff」!■diffdiff はファイル同士の差分を教えてくれるコマンドです。まずは通常の使い方から。例えば、a.txt1 2 3 b.txt1 4 3 のようなファイルがあったとして、diff a.txt b.txt ※変更前、変更後、の順番で指定のように実行すると、2c2 < 2 --- > 4 ※一行目に表示されている英字はそれぞれ a(added)、d(deleted)、c(changed)を示しています※「2c2」は a.txt の二行目から b.txt の二行目に変更があることを示しています ※ `-c` や `-u` オプションを付けると、差分がより見やすい形式で表示されますのように差分箇所を確認することができます。プログラマーで、コード管理を Git や Subversion で行っていれば、ほぼ使う機会もない機能ですが、オプションの組み合わせによって、利用するシーンの幅が広がります。おすすめのオプション組み合わせは `-r` と `-q` と `--exclude` です。diff -rq --exclude=.git src src.back `-r` で複数のファイルを、再帰的に走査し、`-q` で差分のあるファイル名のみを取得し、 `--exclude` で走査不要なディレクトリ・ファイルを指定します。例えば、あまりないとは思いますが、デプロイツールを使わず、cli から直接反映させるようなときに、複数ファイルに渡って反映前後での差分確認に使うことができます。以上、知っておくと、いざという時に便利な diff でした!