2020年10月31日土曜日

ソフトウェアグローバリゼーション入門

 と アプリケーションをつくる英語

いう本を購入しました。また、アプリでは、

■Notepad++

■Typora

の実装を覗いてみました。Typoraは、イギリスの個人事業者だそうで、Open Sourceではありません。ちなみに、。Read.mdは、Typoraで書くことにしました。

2020年10月30日金曜日

サンプルプロジェクトの英語化

 チュートリアルサンプルを英語化しながらやっていますが、色々問題があり、C#をいじっています。訳語、スペース、フォント 等、なるべく日本語に影響しないように作業しています。



2020年10月29日木曜日

プロジェクトファイルのGithub化

 MSIX化で、そのサンプルフォルダをどこにしようか迷いました。ソフトが自由に書けるのは、恐らくAPPDATAですが、隠しフォルダとなっているために、あまりよろしくありませんし、そのような例も探したのですが見当たらず、やはりAppDataを主体にするのはよくない、という結論に達しました。

インストール初期には、あったほうが便利なので一応アタッチしておきますが、更新のしやすさ、ユーザ同士のプロジェクト交換等の便宜を考えると、ダウンロードを主体にしたほうがよさそうだ、という結論に達しました。

なので、プロジェクトの読み込みメニューを追加しました。

https://github.com/sugawara-system/Schedule_Nurse3_Gallery



Github固定ですが、Owner,Repository,Branchを指定するようにしたので、defaultレポジトリに限らず、Githubで公開されているレポジトリであれば、スケジュールナース3で開くことができます。

ダブルクリックすると、プロジェクトを開くことが出来ます。読み込んだ後、プロジェクトは、メモリにありますが、ファイルとしては、未だ存在しないので、名前をつけて適当な場所にプロジェクトを保存してから、求解してください。





2020年10月27日火曜日

ホームページ移転のお知らせ

 ホームページを移転します。新しいサイトは、https://japanese.nurse-scheduling-software.com/ になります。日本語版をサブドメイン、旧アドレスは英語として、Hugoで新しく作る予定です。

現在リンク部の改定作業中です。


2020年10月26日月曜日

C#ソースのDoxygen化

 problem.jsonに関わる部分のDoxygen化を行っています。英語と日本語です。この作業に2日位を見込んでいます。

方法としては、VisualStudioのエディタ上で、Intelisense →コメント挿入 で行っています。

2020年10月25日日曜日

MSIX化その2

<コマンドラインを使う>

 はまりました。VisualStudio上の「公開」を行うと、C#系は、DLL郡をきっちりアタッチしてくれるのですが、C++系プロジェクトについては、EXEだけで、読み込んでいるDLLをアタッチしてくれません。どうにも方法が分からなかったのですが、「公開」+コマンドラインで構築していくことで、必要なファイルをアタッチすることができました。

具体的には、makeappx コマンドとsigntool コマンドを次のようにコンソール上で動かします。最終的には、msixbundleというフォルダが出来ますが、これは、xx_bundleというフォルダに集められたサイニングしたmsixの集合体を指しているようです。最終的に、msibundleにもサイニングして完成になります。


makeappx pack /l /h sha256 /m "C:\Users\sugaw\Documents\Visual Studio 2019\Projects\schedule_nurse_ver3\WindowsFormsApplication1\WapProjTemplate1\WapProjTemplate1\bin\x64\Release\ForBundle\AppxManifest.xml" /f obj\x64\Release\main_map_tak.txt /o /p "C:\Users\sugaw\Documents\Visual Studio 2019\Projects\schedule_nurse_ver3\WindowsFormsApplication1\WapProjTemplate1\WapProjTemplate1\bin\x64\Release\WapProjTemplate1_1.0.30.0_x64.msix"
signtool.exe sign /fd sha256 /a "C:\Users\sugaw\Documents\Visual Studio 2019\Projects\schedule_nurse_ver3\WindowsFormsApplication1\WapProjTemplate1\WapProjTemplate1\bin\x64\Release\WapProjTemplate1_1.0.30.0_x64.msix"
makeappx pack /r /l /h sha256 /m "C:\Users\sugaw\Documents\Visual Studio 2019\Projects\schedule_nurse_ver3\WindowsFormsApplication1\WapProjTemplate1\WapProjTemplate1\bin\x64\Release\ForBundle\AppxManifest.xml" /f obj\x64\Release\split.scale-100.map.txt /o /p "C:\Users\sugaw\Documents\Visual Studio 2019\Projects\schedule_nurse_ver3\WindowsFormsApplication1\WapProjTemplate1\WapProjTemplate1\bin\x64\Release\WapProjTemplate1_1.0.30.0_scale-100.msix"  
signtool.exe sign /fd sha256 /a "C:\Users\sugaw\Documents\Visual Studio 2019\Projects\schedule_nurse_ver3\WindowsFormsApplication1\WapProjTemplate1\WapProjTemplate1\bin\x64\Release\ForBundle\AppxManifest.xml" /f obj\x64\Release\split.scale-100.map.txt /o /p "C:\Users\sugaw\Documents\Visual Studio 2019\Projects\schedule_nurse_ver3\WindowsFormsApplication1\WapProjTemplate1\WapProjTemplate1\bin\x64\Release\WapProjTemplate1_1.0.30.0_scale-100.msix"  
makeappx pack /r /l /h sha256 /m "C:\Users\sugaw\Documents\Visual Studio 2019\Projects\schedule_nurse_ver3\WindowsFormsApplication1\WapProjTemplate1\WapProjTemplate1\bin\x64\Release\ForBundle\AppxManifest.xml" /f obj\x64\Release\split.scale-125.map.txt /o /p "C:\Users\sugaw\Documents\Visual Studio 2019\Projects\schedule_nurse_ver3\WindowsFormsApplication1\WapProjTemplate1\WapProjTemplate1\bin\x64\Release\WapProjTemplate1_1.0.30.0_scale-125.msix"
signtool.exe sign /fd sha256 /a "C:\Users\sugaw\Documents\Visual Studio 2019\Projects\schedule_nurse_ver3\WindowsFormsApplication1\WapProjTemplate1\WapProjTemplate1\bin\x64\Release\ForBundle\AppxManifest.xml" /f obj\x64\Release\split.scale-125.map.txt /o /p "C:\Users\sugaw\Documents\Visual Studio 2019\Projects\schedule_nurse_ver3\WindowsFormsApplication1\WapProjTemplate1\WapProjTemplate1\bin\x64\Release\WapProjTemplate1_1.0.30.0_scale-125.msix"
makeappx pack /r /l /h sha256 /m "C:\Users\sugaw\Documents\Visual Studio 2019\Projects\schedule_nurse_ver3\WindowsFormsApplication1\WapProjTemplate1\WapProjTemplate1\bin\x64\Release\ForBundle\AppxManifest.xml" /f obj\x64\Release\split.scale-150.map.txt /o /p "C:\Users\sugaw\Documents\Visual Studio 2019\Projects\schedule_nurse_ver3\WindowsFormsApplication1\WapProjTemplate1\WapProjTemplate1\bin\x64\Release\WapProjTemplate1_1.0.30.0_scale-150.msix"  
signtool.exe sign /fd sha256 /a "C:\Users\sugaw\Documents\Visual Studio 2019\Projects\schedule_nurse_ver3\WindowsFormsApplication1\WapProjTemplate1\WapProjTemplate1\bin\x64\Release\ForBundle\AppxManifest.xml" /f obj\x64\Release\split.scale-150.map.txt /o /p "C:\Users\sugaw\Documents\Visual Studio 2019\Projects\schedule_nurse_ver3\WindowsFormsApplication1\WapProjTemplate1\WapProjTemplate1\bin\x64\Release\WapProjTemplate1_1.0.30.0_scale-150.msix"  
makeappx pack /r /l /h sha256 /m "C:\Users\sugaw\Documents\Visual Studio 2019\Projects\schedule_nurse_ver3\WindowsFormsApplication1\WapProjTemplate1\WapProjTemplate1\bin\x64\Release\ForBundle\AppxManifest.xml" /f obj\x64\Release\split.scale-400.map.txt /o /p "C:\Users\sugaw\Documents\Visual Studio 2019\Projects\schedule_nurse_ver3\WindowsFormsApplication1\WapProjTemplate1\WapProjTemplate1\bin\x64\Release\WapProjTemplate1_1.0.30.0_scale-400.msix"
signtool.exe sign /fd sha256 /a "C:\Users\sugaw\Documents\Visual Studio 2019\Projects\schedule_nurse_ver3\WindowsFormsApplication1\WapProjTemplate1\WapProjTemplate1\bin\x64\Release\ForBundle\AppxManifest.xml" /f obj\x64\Release\split.scale-400.map.txt /o /p "C:\Users\sugaw\Documents\Visual Studio 2019\Projects\schedule_nurse_ver3\WindowsFormsApplication1\WapProjTemplate1\WapProjTemplate1\bin\x64\Release\WapProjTemplate1_1.0.30.0_scale-400.msix"

copy "C:\Users\sugaw\Documents\Visual Studio 2019\Projects\schedule_nurse_ver3\WindowsFormsApplication1\WapProjTemplate1\WapProjTemplate1\bin\x64\Release\WapProjTemplate1_1.0.30.0_x64.msix" obj\x64\Release\WapProjTemplate1_1.0.30.0_Bundle\*.*
copy "C:\Users\sugaw\Documents\Visual Studio 2019\Projects\schedule_nurse_ver3\WindowsFormsApplication1\WapProjTemplate1\WapProjTemplate1\bin\x64\Release\WapProjTemplate1_1.0.30.0_scale-100.msix" obj\x64\Release\WapProjTemplate1_1.0.30.0_Bundle\*.*
copy "C:\Users\sugaw\Documents\Visual Studio 2019\Projects\schedule_nurse_ver3\WindowsFormsApplication1\WapProjTemplate1\WapProjTemplate1\bin\x64\Release\WapProjTemplate1_1.0.30.0_scale-125.msix" obj\x64\Release\WapProjTemplate1_1.0.30.0_Bundle\*.*
copy "C:\Users\sugaw\Documents\Visual Studio 2019\Projects\schedule_nurse_ver3\WindowsFormsApplication1\WapProjTemplate1\WapProjTemplate1\bin\x64\Release\WapProjTemplate1_1.0.30.0_scale-150.msix" obj\x64\Release\WapProjTemplate1_1.0.30.0_Bundle\*.*
copy "C:\Users\sugaw\Documents\Visual Studio 2019\Projects\schedule_nurse_ver3\WindowsFormsApplication1\WapProjTemplate1\WapProjTemplate1\bin\x64\Release\WapProjTemplate1_1.0.30.0_scale-400.msix" obj\x64\Release\WapProjTemplate1_1.0.30.0_Bundle\*.*
 
makeappx bundle /d obj\x64\Release\WapProjTemplate1_1.0.30.0_Bundle\ /bv 1.0.30.0 /o /p "C:\Users\sugaw\Documents\Visual Studio 2019\Projects\schedule_nurse_ver3\WindowsFormsApplication1\WapProjTemplate1\WapProjTemplate1\AppPackages\WapProjTemplate1_1.0.30.0_Test\WapProjTemplate1_1.0.30.0_x64.msixbundle"  
signtool.exe sign /fd sha256 /a "C:\Users\sugaw\Documents\Visual Studio 2019\Projects\schedule_nurse_ver3\WindowsFormsApplication1\WapProjTemplate1\WapProjTemplate1\AppPackages\WapProjTemplate1_1.0.30.0_Test\WapProjTemplate1_1.0.30.0_x64.msixbundle"  

最初のmakeappx で、/f obj\x64\Release\main_map_tak.txt を行っているのがミソで、オリジナルのmain_map.txtから変更しています。 https://stackoverflow.com/questions/47586254/what-are-mapping-files-for-building-against-uwp-centennial-projects-and-how-do


また、VisualStudio上のプロジェクトだけではなく、スケジュールナース上のサンプルフォルダについても、同様にmapping fileで記述することになります。サンプルフォルダは、いくつかの階層になっていて、ファイル数も多いし、今後のバージョンでも変わっていくので、プロジェクトフォルダ内のファイルをファイルに書き出すプログラムをつくりました。 

using System;
using System.IO;
using System.Text;

namespace ConsoleApp1
{
    class Program
    {
        private static void DirectoryDisplay(StreamWriter w,string sourceDirName,string subname="")
        {
            // Get the subdirectories for the specified directory.
            
            
            DirectoryInfo dir = new DirectoryInfo(sourceDirName);
            //Directory.SetCurrentDirectory(ss2);

            if (!dir.Exists)
            {
                throw new DirectoryNotFoundException(
                    "Source directory does not exist or could not be found: "
                    + sourceDirName);
            }

            DirectoryInfo[] dirs = dir.GetDirectories();

           

            // Get the files in the directory and copy them to the new location.
            FileInfo[] files = dir.GetFiles();
            foreach (FileInfo file in files)
            {
                string s = "\"" + file.FullName + "\" " + "\""+subname+"\\"+file.Name+"\"";
                w.WriteLine(s);
                
            }

            // If copying subdirectories, copy them and their contents to new location.
            
            {
                foreach (DirectoryInfo subdir in dirs)
                {
                    
                    DirectoryDisplay(w,subdir.FullName,subname+"\\"+subdir.Name);
                }
            }
        }


        static void Main(string[] args)
        {
            if (args.Length <= 0) return;
            string dir=args[0];
            var utf8_encoding = Encoding.GetEncoding("utf-8");

            StreamWriter w = new StreamWriter("test.txt",false,utf8_encoding);
            string ss = Directory.GetCurrentDirectory();
            string ss2 = Path.Combine(ss, "..\\");
            string ss3 = Path.Combine(ss2, dir);
            DirectoryDisplay(w,ss3, dir);
            Console.WriteLine("Hello World!");
        }

    }
}
 

スケジュールナースが起動したとき、defaultのインストールフォルダ内に、"プロジェクトサンプル"がないときは、プログラムの実行パスを基点としたプロジェクトサンプルフォルダの内容をコピーするようにしています。

以上で、証明書以外のMSIX化が可能になりました。

<TIPS> MSIX化したパッケージフォルダは、C:Program Files\WindowsApps内にありますが、アクセス権限が強いのか見ることができません。なので、丸ごとWindowsAppsの内容をコピーして、サンプルフォルダ等のアタッチするべきファイルがアタッチされているか、確認しています。

2020年10月24日土曜日

DUNS NUMBERを取得しました

東京商工リサーチの検索では、見つかるものの海外のDUNS NUMBERサーチでは、未だ反映されていないようです。(→海外で反映されるまで2週間程かかるようです。)

 ともあれ、DUNS NUMBER取得と、DomainTransfer作業が完了したので、コードサイニング申請を行いました。業者さんは、日本で一番安いところを選びました。


2020年10月23日金曜日

Cutoisさんの新しい論文

 http://www.schedulingbenchmarks.org/matsp/

で、新しい論文とベンチマークデータセットを見ました。SC3のタスクの概念そのものを使用していますが、残念ながらCoverを達成するための、Shiftを求める問題になっています。シフト時間帯そのものが変数になっているため、シフト時間帯が固定のSC3では、解くことができません。(正確には、そのようなモデリングを意図していないので効率よく解くことはできません。)

残念です。

いつも思うのですが、学術ベンチマークは、役に立たないものを多くてその多くは、人工的に作られています。実際の現場の勤務表ベースのベンチマークというのは、ほとんどないというのが実情です。が、唯一、池上先生が出されているベンチマークは、現場で実際に作られている勤務表がベースになっています。

https://www.nurse-scheduling-software.com/tutorial/benchmarks.htm

このベンチマークの特徴は、全てがソフト制約で記述されていることです。ソフト制約は、

探索空間を削減しません。ですから、ある意味特殊なベンチマークになっていて、実際、ここ数年においても格段の進歩を遂げているGurobi/Cplexでも解くのに、時間がかかる問題です。

2020年10月22日木曜日

DUNSナンバー登録申請2

 屋号を記した通帳コピーを提出したのですが、「スガワラシステムズ」 になっていて、申請の「菅原システムズ」 と違うという指摘をされました。青色申告書のコピーでもよい、と言われて、提出したのですが、「税務署の受領印がないと、駄目」ということでした。

電子申請の場合は、受信通知がはんこの代わりということで、e-Taxソフトにログインして、受信通知をスナショして、送ったら、それでOKということになりました。明日交付予定です。個人事業者で、コードサイニング取得の壁の第一は、DUNSナンバー取得と感じました。



2020年10月19日月曜日

DUNSナンバー登録申請

 個人事業者でも登録可能です。FAQを見ると、屋号の入った通帳があればよさそうです。また、登録申請のWEB画面でも、FAXのない方は、xxxを入れろと親切です。しかし、書類は、なぜかFAXで送る必要があります。コピー機にFAXはついていますが、電話線を引き込むのも面倒なので、秒速FAXを導入しました。送信Onlyでもよく、ポイントチャージ制で、200円からチャージできます。これで十分です。

2020年10月18日日曜日

コードサイニング

コードサイニングとは

 https://qiita.com/Chitama/items/915abc7b872b1e086800

認証局情報

https://www.nda.co.jp/memo/codesigning/index.html

ということで、申請の前にDUNS登録とDomain整備が必要になります。


Domainは、4つ所持しているのですが、名前が載っているドメインは、長年使っていたドメインであり、そのドメインの管理業者と連絡がつかなくなっていました。

消費者センタ、総務省等、手を尽くしましたが、結局届け出のTELにも出ないということで埒が明かず、カナダの上位管理会社(Registrar)と交渉し、ようやくAuthCodeを出してもらい、ドメインを移転することが出来ました。ドメインは移転したのですが、WEBデータ等整備していなかったので、コピーしメールサーバ設定その後DNSを切り替えてドメインの完全切り替え完了となります。従い、

1)DUNS登録

2)Domain整備 whois情報更新

(怪我の功名なのですが、最近は個人情報をさらさなくても独自ドメイン出来ますよ、と謳っている業者さんもあるのですが、名前をさらすことが証明につながる場合もあるということです。)

3)申請

コールバックは、夜中に英語で起こされるのはたまらないので、日本の代理店にしようと思います。

4)コールバック


を経て、ようやくコードサイニングが完了する予定です。その間に、MSIX用のコードに変更する作業を行います。

11月EndにMSIX版に移行を目指そうと思います。


2020年10月17日土曜日

MSIX

 今までインストール時の残念なメッセージが出るのを防止するには、ストアアプリ化するしかないと思っていたのですが、その認識は間違いであることが分かりました。MSIXという新し形式を使い、別にコードサイニングを取得すれば、ストアアプリ化する必要はないことが分かりました。今後の方針としては、

■インストーラをMSIXにする

■コードサイニングを取得維持する

■ソフト本体は無料とする (ライセンス期限を撤廃します)

■Win10 64bit版のみサポート(ビルド1903以降)

しようと思います。MSIX化後は、制約設定・メンテナンス・サポート・コンサルティングが必要な方のみ有償とする予定です。ストアアプリ化はキャンセルします。

MSIXについては、マイクロソフトのビデオを見ながら勉強しているのですが、出てくるエンジニアの方は、Nativeと思われる方はむしろ少なく、インド・フランスその他多様な人達が働いている、米国は本当に懐の深い国だと思いました。

この年にして、AWS LAMBDA, Docker, MSIX と次々に新しい技術を習得しています。最も役立っているのは、Qiitaですが、最後は、やはりStackOverflow 等の英語情報に行き着きます。  



2020年10月16日金曜日

国際祝日対応再び

前に書いた祝日ライブラリは、振り替え休日が定義されていないことが分かってドロップしました。そこで、下記で言及されているライブラリを採用することにしました。

ただし、javascriptなので、C#では、そのままでは、動作しません。そこで、
次のように、オフラインで、2035年までJSONを吐かせてそれをファイルとして搭載することにしました。
#!/usr/bin/env node

/**
 * draw tree of supported countries, states, regions
 */
function country_draw(stream,hd,country,country_name,state,state_name,region,region_name){
  hd.init(country)
    
    var holidays=hd.getHolidays(2015)
    for (y=2016;y< 2035 -="" 10="" 1="" :="" console.dir="" console.log="" const="" countries="" countrieslen="" country="" country_code="" country_name="" d="" date-holidays="" date="" draw="[" dt.getdate="" dt.getmonth="" dt="new" else="" for="" foreach="" function="" hd="new" holiday.substitute="" holiday.type="=" holiday="" holidays1="hd.getHolidays(y)" holidays="" i="" if="" m="" maxarraylength:="" maxarraylength="" msec="" n="" null="" object.keys="" of="" ountries:="" public="" public_holidays.push="" public_holidays="" region="" region_code="" region_name="" slice="" state="" state_code="" state_name="" str="" stream="" substitute_holidays.push="" substitute_holidays="" t="" tree="" util.inspect="" util="" var="" y="dt.getFullYear();"> {
    const d = (i === countriesLen ? draw[1] : draw[0])
    //console.log(d + country + ': ' + countries[country] + '\n')
    const hd = new Holidays()
    if (i!=0) console.log(",");
    country_draw(stream,hd,country,countries[country],"","","","")
    const states = Holidays().getStates(country)
    if (states) {
      const statesLen = Object.keys(states).length - 1
      Object.keys(states).forEach((state, j) => {
        let d = (i === countriesLen ? draw[3] : draw[2])
        d += (j === statesLen ? draw[1] : draw[0])
        //console.log(d + state + ': ' + states[state] + '\n')
        console.log(",");
   	country_draw(stream,hd,country,countries[country],state,states[state],"","")

        const regions = Holidays().getRegions(country, state)
        if (regions) {
          const regionsLen = Object.keys(regions).length - 1
          Object.keys(regions).forEach((region, k) => {
            let d = (i === countriesLen ? draw[3] : draw[2])
            d += (j === statesLen ? draw[3] : draw[2])
            d += (k === regionsLen ? draw[1] : draw[0])
            //console.log(d + region + ': ' + regions[region] + '\n')
	console.log(",");
   	country_draw(stream,hd,country,countries[country],state,states[state],region,regions[region])

          })
        }
      })
    }
  })
}
module.exports = tree

if (module === require.main) {
    console.log("{'members':[\n")
  tree(process.stdout)
  console.log("]\n")
  console.log("}\n")
}

定義済み曜日の祝をクリックするとComboboxが出現します。
国だけではなくて、米国のようにState、さらにRegionまで必要な場合もあるんですね。

2020年10月15日木曜日

UI Debug

 API Gateway呼び出しでは、慣れないawait/asyncを使っています。その際、UIでのデバッグでは、こちらを参考にしています。

https://qiita.com/ken_hamada/items/501b164374667319d270

A)背景の一番後ろが、DebugViewというツールで、C#のデバッグ出力です。
B)2番目が、UIをループされているプログラムで、上記サイトの電卓操作のプログラムを改造してスケジュールナース用の求解ボタンを叩いています。AWSのLambdaのコールドスタートタイミングに絡んでいそうなので、数分待って叩くループにしています。
C)3番目が、同作者のツールでAutomationIDを拾ってくれます。開発環境はリモートデスクトップでつながった、マイクもDisplayもないマシンでそのままでは、動かなかったので、音声入力のC#ソースは、カットしています。

なぜか、リモートデスクトップを最小化するとスリープに入るためか、B)がクラッシュしてしまいます。が、最小化しないで、画面の片隅に置いておけば大丈夫なようです。


2020年10月14日水曜日

Grammerly Premium を導入

 今まで無料版を使っていたのですが、Premiumに移行しました。DeepLとの併用で、かなり作業効率がよさそうです。楽しく英文を添削してくれます。






練習を兼ねてSDK2.1 Nurse Scheduling Solver AWS Lambda Engineの動画を作ってみました。

https://www.youtube.com/watch?v=UBkmB0LYVUc&feature=youtu.be

2020年10月13日火曜日

REST API検討

 APIを構築して、それに対してサービスを構築するというのが、一般的なのでしょうが、今回は、そのアプローチは採っていません。真にユーザの利便を考えたときに、Lambdaが直接呼べる環境があるのであれば、直接呼んで頂いた方が良いと信じるからです。顧客毎のクローズドな世界となり顧客毎の対応が必要となりますが、何かトラブルがあっても他のお客さまは、影響を受けないというメリットもあります。

ということで、APIGatewayを敢えて構築する必要はない訳ですが、AWS外から呼ぶとすれば、APIGatewayを介することは必須であります。アカウントIDとSecretKeyをプログラムにぶち込んでAWS外からダイレクトに呼ぶことも不可能ではありませんが、アカウント情報をそのような形で入れることは、危険極まりない行為です。ハッカには太刀打ちできません。

SDKサンプルとして構築してみました。API-Gatewayは、初めてでしたが、3日位で動くようになりました。その際、REST APIについて調べてみました。

https://qiita.com/TakahiRoyte/items/949f4e88caecb02119aa

https://qiita.com/masato44gm/items/dffb8281536ad321fb08

https://qiita.com/mserizawa/items/b833e407d89abd21ee72


2020年10月12日月曜日

newtonsoft C# problem.jsonのダイエット

 AWS Lambda非同期コールや、AWS STEP FUNCTIONでは、payloadサイズが256KB程度に制限されています。具体的には、ソルバーに投げるpayload sizeがこのサイズを超えているとLambdaに届くまえにはじかれてしまいます。SC3GUIでは、1MBのproblem.jsonも普通にありえるので、なるべくこのサイズが、256KB以下になるようにすることが目的です。(サイズを超えたらS3を使います。DynamodbでもItemSizeが制限されているので不適です。)

SC3 GUIでは、Jsonのシリアライザにnewtonsoftを使っています。このオプションを使うことで、ある程度ダイエットが可能です。

<方法1 インテンドなしにする>
#if REDUCE_JSON
            Newtonsoft.Json.JsonSerializerSettings settings = new Newtonsoft.Json.JsonSerializerSettings { Converters = { new CustomDateTimeConverter() },Formatting = Newtonsoft.Json.Formatting.None };
#else
             Newtonsoft.Json.JsonSerializerSettings settings = new Newtonsoft.Json.JsonSerializerSettings { Converters = { new CustomDateTimeConverter() },Formatting = Newtonsoft.Json.Formatting.Indented };//, Forma
#endif


こうすると、読みやすいJSONが

{
  "SO": {
    "name": "Shift Objects",
    "members": [
      {
        "use": true,
        "name": "ShiftDef",
        "def_name": "日勤",
        "auto_schedule": true,
        "color": "LightGray",
        "label": "・",
        "another_labels": [
          "",
          ""
        ],

読みにくくなります。これが一番効果がありました。

{"SO":{"name":"Shift Objects","members":[{"use":true,"name":"ShiftDef","def_name":"日勤","auto_schedule":true,"color":"LightGray","label":"日","another_labels":["",""],"another_colors":

<方法2 default valueを使う。defaultの値を定義しておいて、それと同じだったらJSON化されません。> 方法1と2を用いることで、サイズが1/4から1/5程度になりました。

#if REDUCE_JSON
        [ DefaultValue("")]//OCT042020
        [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
#endif
        public string shift;
        //OCT042020
#if REDUCE_JSON
        [DefaultValue(0)]
        [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
    public int level;
#endif

2020年10月11日日曜日

API GATEWAY  Single Quote でServer Error を対策


Jsonペイロード中にあってはいけないのか、よく分かっていませんが、例えば、Pythonのコードのように、PythonコードがあるとSingleQuoteが発生します。 newtonsoftでこれをシリアライズていますが、Escapeしてくれません。そのままPayloadに乗ってAPIGateway通過時にServerErrorとなるようです。
import sc3
sc3.print('Hello Python3 Constraint World!\n')

そこで、PythonのREST API デモコードでは、次のようにしました。
json_open = open('problem.json', 'r') #Read problem.json file
json_load = json.load(json_open)#conver to dictionary

json_load["SolP"]["external_constraint_python"]=json_load["SolP"]["external_constraint_python"].replace('\'','\"') #Web API seems to reject Single Quote 

import sc3
sc3.print('Hello Python3 Constraint World!\n')

C# REST API デモコードでは、安直にDoubleQuoteのEsaceとしました。
 string rep_str = problem_server_string.Replace("'", "\\\"");//API Server dislikes ' 

2020年10月10日土曜日

AWS Lambda Broken Pipe

REST APIを作成中、S3や、DyanamodbをC++でいじっていて、上記のエラーが不定期にでてLambdaがクラッシュしてしまいます。(下図で、API Gateway後のLambda)





原因は良く分かっていないのですが似た症状のレポートがありました。

https://github.com/aws/aws-sdk-cpp/issues/959

これによれば、

options.HttpOptions.installSigPipeHandler = true;


にするとのこと。SDK sampleでもそのようなcodeにはなっていないのですが、なぜか

上記の通りするとクラッシュが収まりました。

2020年10月2日金曜日

Linux Time 変換

AWS Lambdaのライセンスは、LinuxTimeで行うことにしました。

なので、LinuxTime(64bit)と日付との相互変換が必要になります。

 ありました。

https://tool.konisimple.net/date/unixtime

2020年10月1日木曜日

AWS API GATEWAYでARNを暴露しない

 AWS LAMBDA は、内から呼ぶ分には、CREDENTIAL情報は、必要なく適当なIAMを設定してやれば、ACCESSIDをプログラムコードに入れる必要はありません。たとえば、

https://qiita.com/itoa06/items/614fc3322f83512cab3b

<LAMBDAをAPI GATEWAYから呼ぶときの問題>

問題は、API GATEWAYのタイムアウトが29secです。LAMBDAがこの時間内に解ける保証はありません。そこで、STEP FUNCTIONを使用して、API GATEWAYのタイムアウトを避けつつ、LAMBDAの解の到着をポーリングで待ちます。

https://dev.classmethod.jp/articles/apigateway-stepfunctions-asynchronous/

上記の手法で、実装してみました。StepFUNCTION StartExecutionでLAMBDAをFireし、DescribeExecutionでポーリングします。

<StartExecution とDescribe Executionの問題>

ところが、上記そのままですと、ARNが暴露されてしまいます。

<解決策>

ありました。下記です。

https://medium.com/@cody_green/using-aws-api-gateway-and-step-functions-without-exposing-your-arn-ce94a88fa594