tag:blogger.com,1999:blog-54717059967450809012024-03-13T09:39:08.613-04:00Ovi CrisanCloud Solution ArchitectOvi Crisanhttp://www.blogger.com/profile/11384935190005442742noreply@blogger.comBlogger47125tag:blogger.com,1999:blog-5471705996745080901.post-89710127648540343242021-07-05T22:03:00.002-04:002021-07-05T22:03:31.870-04:00Pineapple<p> I started today a new chapter in my professional name: Enterprise Architect at <a href="https://gopineapple.com" target="_blank">Pineapple</a>.</p><p>Actually, they also started a new chapter today, rebranding from previously known Capital Lending Centre.</p><p>I'm very exited for this new position responsible for many IT & development aspects, at the core of a tech focused young company. Go Pineapple!</p>Ovi Crisanhttp://www.blogger.com/profile/11384935190005442742noreply@blogger.com0tag:blogger.com,1999:blog-5471705996745080901.post-76572977972692292302021-06-12T00:13:00.002-04:002021-06-12T00:13:14.877-04:00Salesforce Ideas<p>Salesforce has that nice feature to allow users suggest and vote on new ideas to be implemented. There are many times when the feature you are looking for is not there and if you'd contact Salesforce support they just suggest to vote that specific idea, which very likely was already proposed.</p><p>But this is also a two edged sword because also allow you to see what is actually missing from Salesforce and highly requested by their customers: <a href="https://trailblazer.salesforce.com/ideaSearch?sort=2" target="_blank">IdeaExchange</a> sorted by popular items.</p><p>Surprised to see proposals made more than 10 years ago and voted or commented by thousands? Don't be. this is the reverse of the coin which many times the manuals are just forgetting to mention.</p><p>I voted some, but not too many, as I don't think that the sheer number of votes matter too much.</p>Ovi Crisanhttp://www.blogger.com/profile/11384935190005442742noreply@blogger.com0tag:blogger.com,1999:blog-5471705996745080901.post-11810252531092959732021-06-11T23:59:00.002-04:002021-06-11T23:59:26.257-04:00Some more free services available with an Azure free account<p> Microsoft added some more services for their Azure free account:</p><p></p><ul style="text-align: left;"><li>Azure Database for PostgreSQL</li><li>Azure Database for MySQL</li><li>Azure Key Vault</li><li>Azure Logic Apps</li></ul><p></p><p>Nice. Some more reasons to start trying <a href="https://www.azure.com/free" target="_blank">Azure for free</a>.</p>Ovi Crisanhttp://www.blogger.com/profile/11384935190005442742noreply@blogger.com0tag:blogger.com,1999:blog-5471705996745080901.post-15715958908892483702021-05-01T08:29:00.003-04:002021-05-01T08:31:35.342-04:00Microsoft Certified: Azure Solutions Architect Expert<p> I passed yesterday AZ-303 exam so now I call myself </p><p><br /></p><p style="text-align: center;"><a href="https://www.credly.com/earner/earned/badge/e3f19529-e6d8-4af9-9ec6-1347a912fd0b" target="_blank"><img height="340" src="https://images.credly.com/size/680x680/images/987adb7e-49be-4e24-b67e-55986bd3fe66/azure-solutions-architect-expert-600x600.png" v="" width="340" /></a></p><p>Yay!</p><p>Next step: data engineer associate, coming soon.</p>Ovi Crisanhttp://www.blogger.com/profile/11384935190005442742noreply@blogger.com0tag:blogger.com,1999:blog-5471705996745080901.post-65769042535912113812021-04-26T09:17:00.005-04:002021-04-26T09:17:55.042-04:00AZ-304 certificationI passed yesterday Microsoft's AZ-304 certification, one step towards Azure Solutions Architect Expert.<div><br /></div><div>I prepared pretty well for this exam so I didn't find it too difficult. I used Pluralsight series for this exam, Sybex's <i>Microsoft Azure Architect Technologies and Design</i> (Study Guide), plus a few other materials including quite a lot MS documentation (read well <i>Overview </i>or <i>FAQ </i>pages), but I found interesting Mark Grimes' YouTube videos (<a href="https://www.youtube.com/watch?v=VYcRbueAVEs&t=334s" target="_blank">1</a>, <a href="https://www.youtube.com/watch?v=j0Mop8fFDj4&t=5s">2</a>, ...).</div><div><br /></div><div>Next obvious step is AZ-303 scheduled in a few days. Sure is easier to prepare for both at the same time.</div><div><br /></div><div>The only negative was waiting an hour on VUE online app to be verified before starting the exam. They talk about 15 minutes but in my case was a full hour.</div>Ovi Crisanhttp://www.blogger.com/profile/11384935190005442742noreply@blogger.com0tag:blogger.com,1999:blog-5471705996745080901.post-49109875673410186272020-12-01T14:36:00.006-05:002020-12-01T14:38:50.965-05:00PMI-ACP renewal PDUs<p> Also today I've just finished the last online course to maintain my PMI-ACP certification, due for renewal in Feb 2021. For this cycle of 3 years I had to do 30 PDUs to maintain it.</p><p>For last few days I was watching some videos, approved by PMI, to earn those PDUs. As you may know, the rule of thumb is 1 PDU for 1 hour of conference or virtual event, so you can do the math. Quite a lot of information to review all theory tested by ACP exam, and even more.</p><p></p><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/--BjqmUp5VSU/X8aaDo03ZtI/AAAAAAAAAOY/JT4DLRUeD9YD-xUU7fJ4BDgsNnsiIjIdQCLcBGAsYHQ/s1324/pdus.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="223" data-original-width="1324" height="68" src="https://1.bp.blogspot.com/--BjqmUp5VSU/X8aaDo03ZtI/AAAAAAAAAOY/JT4DLRUeD9YD-xUU7fJ4BDgsNnsiIjIdQCLcBGAsYHQ/w400-h68/pdus.png" width="400" /></a></div><div style="text-align: left;"><br /></div></div><p></p>Ovi Crisanhttp://www.blogger.com/profile/11384935190005442742noreply@blogger.com0tag:blogger.com,1999:blog-5471705996745080901.post-10335601014435408252020-12-01T14:22:00.004-05:002020-12-01T14:23:08.030-05:00Salesforce Sharing and Visibility Designer certification<p>Two days ago I got my 3rd Salesforce certification, Sharing and Visibility Designer:</p><div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-ztHFS4GvU9o/X8aXqavgDOI/AAAAAAAAAOE/au94RWGYPFcJbkNTxGtv1WGKKt_MCmeagCLcBGAsYHQ/s1095/Salesforce_Sharing_and_Visibility.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="824" data-original-width="1095" height="301" src="https://1.bp.blogspot.com/-ztHFS4GvU9o/X8aXqavgDOI/AAAAAAAAAOE/au94RWGYPFcJbkNTxGtv1WGKKt_MCmeagCLcBGAsYHQ/w400-h301/Salesforce_Sharing_and_Visibility.png" width="400" /></a></div><br /><p>This is the 1st one for architect level, one more to go for Salesforce solution architect. Yay!</p>Ovi Crisanhttp://www.blogger.com/profile/11384935190005442742noreply@blogger.com0tag:blogger.com,1999:blog-5471705996745080901.post-5014150833553347232020-11-25T21:01:00.001-05:002020-11-25T21:01:45.415-05:00ServiceNow certification<p>I got my ServiceNow Admin certification more than 2 year ago and since then I took a few delta exams, an open-book exam about changes introduced by new releases. Until now those delta exams were free, and mandatory to maintain the certification, but with current release ("Paris") they introduced a $200 annual fee.</p><p>It was <a href="https://community.servicenow.com/community?id=community_blog&sys_id=20d5a9d2dbb5d0106c1c02d5ca9619b6" target="_blank">announced</a> almost half a year ago but I didn't actually pay attention to that small detail. Today I received an email reminding me the calendar, as the exam should happen before Jan 7th, 2021.</p><p>Sorry ServiceNow, but I think I'll just let this certification expire. My initial plans were different and didn't use this certification at all, so paying $200 / year just to maintain it is out of question. I intend to maintain some other certifications I have, and I'd do it for ServiceNow, too, if they were free, but not in these new conditions they introduced.</p>Ovi Crisanhttp://www.blogger.com/profile/11384935190005442742noreply@blogger.com0tag:blogger.com,1999:blog-5471705996745080901.post-48812907224137574092020-11-11T10:25:00.001-05:002020-11-11T10:25:40.409-05:00.NET 5.0<p><a href="https://devblogs.microsoft.com/dotnet/announcing-net-5-0/" target="_blank">Launched yesterday</a> at <a href="https://dotnetconf.net" target="_blank">dotnetconf.net</a> I've just installed .NET 5.0:</p><p></p><ul style="text-align: left;"><li>Downloaded and installed <a href="https://dotnet.microsoft.com/download/dotnet/5.0" target="_blank">.NET 5 SDK</a>. Checked.</li><li>Updated Visual Studio to 18.6. Checked.</li><li>Read the release notes. Checked.</li><li>Read <a href="https://devblogs.microsoft.com/dotnet/announcing-the-release-of-ef-core-5-0/" target="_blank">EF Core 5.0</a> release notes. Checked.</li><li>Watch dotnetconf.net. Checked.</li></ul><div>No more release candidate version, and no more .NET Core (except EF), but one unified platform. I'd like that, when all parts will be ready.</div>Ovi Crisanhttp://www.blogger.com/profile/11384935190005442742noreply@blogger.com0tag:blogger.com,1999:blog-5471705996745080901.post-31497267599595290722020-11-02T20:55:00.001-05:002020-11-02T20:55:49.955-05:00Salesforce platform developer 1 certification<p> As planned, today I took and happily passed my 2nd Salesforce certification: platform developer 1.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-jcsLiSoFnW8/X6C38XnbbwI/AAAAAAAAANw/CrVyQy117k4vMLfvmFC_R1cq0OJaB_rIgCLcBGAsYHQ/s975/Salesforce_Platform_Dev_1.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="735" data-original-width="975" height="301" src="https://1.bp.blogspot.com/-jcsLiSoFnW8/X6C38XnbbwI/AAAAAAAAANw/CrVyQy117k4vMLfvmFC_R1cq0OJaB_rIgCLcBGAsYHQ/w400-h301/Salesforce_Platform_Dev_1.png" width="400" /></a></div><br /><p>The next one for Salesforce Application Architect credential path will have to wait a while, as the preparation for it will take a bit longer, but hopefully will come.</p>Ovi Crisanhttp://www.blogger.com/profile/11384935190005442742noreply@blogger.com0tag:blogger.com,1999:blog-5471705996745080901.post-71307665082415796542020-10-28T13:37:00.001-04:002020-10-28T13:38:12.242-04:00Salesforce certifications<p> I played with my own org in Salesforce for a while, but lately a few things aligned, mainly the company I'm working for just moved to Salesforce. It was a pretty big move, delivered by a big name in consulting services, but now slowly we (app dev department) have to take more and more on the support part. So I decided to get certified with Salesforce.</p><p>Besides this, the company also moved to DocuSign (of course, for e-signatures), which happily integrates with Salesforce. Again we had some consultants working on this, but that sparked also my interest.</p><p>DocuSign has <a href="https://developers.docusign.com/" target="_blank">free developer instances</a>, which I registered and <a href="https://appexchange.salesforce.com/appxListingDetail?listingId=a0N30000001taX4EAI">integrated with Salesforce</a> (dev org). Then, registered with <a href="https://dsu.docebosaas.com/">DocuSign University</a> (separate registration), reading the docs, testing and tried (successfully) a first certification: <a href="https://www.youracclaim.com/badges/54640661-eba4-49b2-b412-202d1630f7df">DocuSign eSignature Template Specialist 2020</a>. Then a more important one I was interested, <a href="https://www.youracclaim.com/badges/c76c2f79-9e96-416a-9d64-ed2a1312dc29">DocuSign eSignature for Salesforce Specialist 2020</a> (after reading and testing the <a href="https://support.docusign.com/en/guides/docusign-for-salesforce-administrator-guide?">manual</a> + University exercises). Yay! It worked, and even better, all free.</p><p>Then the focus was back to Salesforce certification, which I prepared for quite some time. First one is <a href="https://trailhead.salesforce.com/help?article=Salesforce-Certified-Platform-App-Builder-Exam-Guide">App Builder</a> which I passed 2 days ago:</p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://lh3.googleusercontent.com/-JrkhVyuJDGk/X5mqeLCRZeI/AAAAAAAAANk/S__1S-CwGlwJTYYeinLfMQxPlWyPrUzwQCLcBGAsYHQ/image.png" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="601" data-original-width="800" height="301" src="https://lh3.googleusercontent.com/-JrkhVyuJDGk/X5mqeLCRZeI/AAAAAAAAANk/S__1S-CwGlwJTYYeinLfMQxPlWyPrUzwQCLcBGAsYHQ/w400-h301/image.png" width="400" /></a></div><br />Yay again! Next one is logically Salesforce Platform Developer 1, which I intend to try in a few days. Hopefully I'll have good news on this one too, very soon.<p></p><p>Keeping busy these special conditions of working from home.</p>Ovi Crisanhttp://www.blogger.com/profile/11384935190005442742noreply@blogger.com0tag:blogger.com,1999:blog-5471705996745080901.post-59552086644981442462020-07-20T20:12:00.000-04:002020-07-20T20:12:13.827-04:00ASP.NET Core trick: breakpoint for 404 errorsI had an 404 error for a test web app that used a NGINX reverse-proxy config file, which was pretty hard to track it down. Most of the routes worked fine, except pages under an <i>/admin</i> folder, all throwing 404 error, page not found.<br />
<br />
The easiest thing to track it down is a break-point somewhere, but where exactly, for a page that's not found? So, I added temporarily a middleware in Startup.cs, <a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/" target="_blank">by the book</a>:<br />
<br />
app.Use(async (context, next) =><br />
{<br />
<span style="white-space: pre;"> </span>// Do work that doesn't write to the Response.<br />
<span style="white-space: pre;"> </span><span style="background-color: #fff2cc;">await next.Invoke();</span><br />
<span style="white-space: pre;"> </span>// Do logging or other work that doesn't write to the Response.<br />
});<br />
<br />
Then just add the break-point on highlighted line and inspect the Request object.<br />
<br />
In my case I only needed a backslash in <i>proxy_pass</i> parameter of NGINX's config file.Ovi Crisanhttp://www.blogger.com/profile/11384935190005442742noreply@blogger.com0tag:blogger.com,1999:blog-5471705996745080901.post-48833258668734816252020-05-25T16:06:00.001-04:002020-05-25T16:12:36.601-04:00IPython Notebook to connect to SQL Server 2019I installed Anaconda 3 some time ago, and then I installed SQL Server 2019 without ML libraries for Python. Now I just wanted to connect from an IPython Notebook to this local named instance of SQL Server, directly.<br />
<br />
I tried with both <i>pyodbc </i>(which worked from first try) and <i>pymssql </i>which seemed to have some issue. The error message was:<br />
<br />
"<b style="background-color: white; font-family: Consolas, "Courier New", monospace; font-size: 14px; white-space: pre-wrap;"><span style="color: var(--vscode-terminal-ansiBrightRed);">MSSQLDatabaseException</span></b><span style="background-color: white; font-family: "consolas" , "courier new" , monospace; font-size: 14px; white-space: pre-wrap;">: (20009, b'DB-Lib error message 20009, severity 9:\nUnable to connect: Adaptive Server is unavailable or does not exist (localhost\\SQLSRV2019)\n')"</span><br />
<span style="background-color: white; font-family: "consolas" , "courier new" , monospace; font-size: 14px; white-space: pre-wrap;"><br /></span>
<br />
<span style="font-family: "consolas" , "courier new" , monospace;"><span style="background-color: white; font-size: 14px; white-space: pre-wrap;">It looks like pymssql library needs the TCP/IP connection configuration to be enabled, and also needs <i>SQL Server Browser</i> service to run. So, start </span><span style="font-size: 14px; white-space: pre-wrap;"><i>SQL Server 2019 Configuration Manager</i> and then <i>Enable </i>TCP/IP configuration setting:</span></span><br />
<span style="font-family: "consolas" , "courier new" , monospace;"><span style="font-size: 14px; white-space: pre-wrap;"><br /></span></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-TlsIOt0B0sA/XswgZsVSzCI/AAAAAAAAAMQ/zllLAtMaJ2MrMdwamnWyaKRXCxk3oWStwCLcBGAsYHQ/s1600/pymssql1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="263" data-original-width="675" height="249" src="https://1.bp.blogspot.com/-TlsIOt0B0sA/XswgZsVSzCI/AAAAAAAAAMQ/zllLAtMaJ2MrMdwamnWyaKRXCxk3oWStwCLcBGAsYHQ/s640/pymssql1.png" width="640" /></a></div>
<span style="font-family: "consolas" , "courier new" , monospace;"><span style="font-size: 14px; white-space: pre-wrap;"><br /></span></span><span style="font-family: "consolas" , "courier new" , monospace;"><span style="font-size: 14px; white-space: pre-wrap;">And in Windows <i>Services.msc</i> make sure <i>SQL Server Browser</i> runs:</span></span><br />
<span style="font-family: "consolas" , "courier new" , monospace;"><span style="font-size: 14px; white-space: pre-wrap;"><br /></span></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-SyV3ts3RfV0/XswhW-UABtI/AAAAAAAAAMY/Zokdbhx06vke9nfdwi8Pmtrx_d9rHJRhgCLcBGAsYHQ/s1600/pymssql2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="334" data-original-width="1135" height="187" src="https://1.bp.blogspot.com/-SyV3ts3RfV0/XswhW-UABtI/AAAAAAAAAMY/Zokdbhx06vke9nfdwi8Pmtrx_d9rHJRhgCLcBGAsYHQ/s640/pymssql2.png" width="640" /></a></div>
<span style="font-family: "consolas" , "courier new" , monospace;"><span style="font-size: 14px; white-space: pre-wrap;"><br /></span></span><span style="font-family: "consolas" , "courier new" , monospace;"><span style="font-size: 14px; white-space: pre-wrap;">After these changes restart SQL Server 2019 instance (don't forget this step).</span></span><br />
<span style="font-family: "consolas" , "courier new" , monospace;"><span style="font-size: 14px; white-space: pre-wrap;"><br /></span></span>
<span style="font-family: "consolas" , "courier new" , monospace;"><span style="font-size: 14px; white-space: pre-wrap;">The code for pyodbc:</span></span><br />
<blockquote class="tr_bq">
<div style="background-color: white; line-height: 19px;">
<span style="font-family: "consolas" , "courier new" , monospace;"><span style="font-size: 14px; white-space: pre-wrap;">import pyodbc
conn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER=.\SQLSRV2019;DATABASE=db1;UID=sa;PWD=***')
cursor = conn.cursor()
cursor.execute("select id1, name1 from Table1")
rows = cursor.fetchall()
print(rows)</span></span></div>
</blockquote>
<span style="font-family: "consolas" , "courier new" , monospace;"><span style="font-size: 14px; white-space: pre-wrap;">The code for pymssql with Pandas DataFrame:</span></span><br />
<blockquote class="tr_bq">
<div style="background-color: white; line-height: 19px;">
<span style="font-family: "consolas" , "courier new" , monospace;"><span style="font-size: 14px; white-space: pre-wrap;">import pymssql
import pandas as pd
conn = pymssql.connect(user = 'sa', password = '***', host='.\SQLSRV2019', database = 'db1')
q = pd.read_sql_query('select name1, id1 from Table1', conn)
conn.close()
df = pd.DataFrame(q, columns=['name1','id1'])
print(df)</span></span></div>
</blockquote>
<span style="font-family: "consolas" , "courier new" , monospace;"><span style="font-size: 14px; white-space: pre-wrap;">Then let's plot the values with <i>matplotlib</i>:</span></span><br />
<blockquote class="tr_bq">
import matplotlib.pyplot as plt<br />
df.plot(kind='bar')</blockquote>
<span style="background-color: white; font-family: "consolas" , "courier new" , monospace; font-size: 14px; white-space: pre-wrap;">You can try these with either JupyterLab / Jupyter Notebook from Anaconda 3 or even with <a href="https://marketplace.visualstudio.com/items?itemName=ms-python.anaconda-extension-pack" target="_blank">VS Code extension for Anaconda</a>.</span>Ovi Crisanhttp://www.blogger.com/profile/11384935190005442742noreply@blogger.com0tag:blogger.com,1999:blog-5471705996745080901.post-82214689225549960362020-02-10T10:49:00.003-05:002020-02-10T10:49:34.539-05:00Azure Key Vault—Private endpoints now available in preview"<span style="background-color: white; color: #4c4c51; font-family: "Segoe UI", SegoeUI, "Segoe WP", Tahoma, Arial, sans-serif; font-size: 16px;">Establish a private connection between Azure Key Vault and other Azure services by using </span><a data-bi-area="content" data-bi-id="page-clicked-link" data-event="page-clicked-link" href="https://azure.microsoft.com/en-us/services/private-link/" style="background-color: white; box-sizing: inherit; color: #0062ad; font-family: "Segoe UI", SegoeUI, "Segoe WP", Tahoma, Arial, sans-serif; font-size: 16px; transition: color 0.15s ease-in-out 0s;" target="_blank">Azure Private Link</a><span style="background-color: white; color: #4c4c51; font-family: "Segoe UI", SegoeUI, "Segoe WP", Tahoma, Arial, sans-serif; font-size: 16px;">, now available in preview for all public regions.</span><br />
<span style="background-color: white; color: #4c4c51; font-family: "Segoe UI", SegoeUI, "Segoe WP", Tahoma, Arial, sans-serif; font-size: 16px;">[...]</span><br />
<span style="background-color: white; color: #4c4c51; font-family: "Segoe UI", SegoeUI, "Segoe WP", Tahoma, Arial, sans-serif; font-size: 16px;">All traffic to the service can be routed through the private endpoint, so no gateways, NAT devices, ExpressRoute or VPN connections, or public IP addresses are needed. Traffic between your virtual network and the service traverses over the Microsoft backbone network, eliminating exposure from the public Internet.</span><span style="background-color: white; color: #4c4c51; font-family: "Segoe UI", SegoeUI, "Segoe WP", Tahoma, Arial, sans-serif; font-size: 16px;">"</span><br />
<span style="background-color: white; color: #4c4c51; font-family: "Segoe UI", SegoeUI, "Segoe WP", Tahoma, Arial, sans-serif; font-size: 16px;"><br /></span>
<span style="background-color: white; color: #4c4c51; font-family: "Segoe UI", SegoeUI, "Segoe WP", Tahoma, Arial, sans-serif; font-size: 16px;">A question may be why only now? It should have been there from the beginning.</span><br />
<span style="background-color: white; color: #4c4c51; font-family: "Segoe UI", SegoeUI, "Segoe WP", Tahoma, Arial, sans-serif; font-size: 16px;"><br /></span>
<span style="background-color: white; color: #4c4c51; font-family: "Segoe UI", SegoeUI, "Segoe WP", Tahoma, Arial, sans-serif; font-size: 16px;">Docs <a href="https://docs.microsoft.com/en-us/azure/key-vault/private-link-service" target="_blank">link</a>.</span>Ovi Crisanhttp://www.blogger.com/profile/11384935190005442742noreply@blogger.com0tag:blogger.com,1999:blog-5471705996745080901.post-43030138759854300682019-11-24T11:55:00.004-05:002019-11-24T12:01:29.929-05:00ContactForm.Sample project on GitHubI added a new demo project called <i>ContactForm.Sample</i> at <a href="https://github.com/ovicrisan/ContactForm.Sample">github.com/OviCrisan/ContactForm.Sample</a>. It's just a sample solution with 2 projects, one to show a contact form with both C# and JS / AJAX, which then uses HTTP POST to a web API project, which saves data to a Postgres database. The web API (<i>Contactform.Sample.Postgres</i>) is build as a separate infrastructure project because I intend to add some more API projects for other databases, SQL and no-SQL.<br />
<br />
Here's a simple diagram of the projects:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://camo.githubusercontent.com/37bd10db573c35f30de8b81cb56c29aec46dbc22/68747470733a2f2f6f766963726973616e2e6769746875622e696f2f436f6e74616374466f726d2e53616d706c652f436f6e74616374466f726d2e53616d706c652e312e706e67" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="274" data-original-width="800" height="218" src="https://camo.githubusercontent.com/37bd10db573c35f30de8b81cb56c29aec46dbc22/68747470733a2f2f6f766963726973616e2e6769746875622e696f2f436f6e74616374466f726d2e53616d706c652f436f6e74616374466f726d2e53616d706c652e312e706e67" width="640" /></a></div>
And the regular C# web form with Google reCAPTCHA (demo) enabled:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://camo.githubusercontent.com/bf9e5a8f465ad40602a80157a103dd3e4e3fd097/68747470733a2f2f6f766963726973616e2e6769746875622e696f2f436f6e74616374466f726d2e53616d706c652f436f6e74616374466f726d2e53616d706c652e322e706e67" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="521" data-original-width="800" height="416" src="https://camo.githubusercontent.com/bf9e5a8f465ad40602a80157a103dd3e4e3fd097/68747470733a2f2f6f766963726973616e2e6769746875622e696f2f436f6e74616374466f726d2e53616d706c652f436f6e74616374466f726d2e53616d706c652e322e706e67" width="640" /></a></div>
<br />
More technical details are added to <a href="https://github.com/ovicrisan/ContactForm.Sample/blob/master/readme.md" target="_blank">readme files</a> in the project source code, including details to run it with Docker compose from Docker containers.<br />
<br />
By the way, the project Docker images are also available on Docker Hub <a href="https://hub.docker.com/repository/docker/ovicrisan/contactformsample" target="_blank">here</a> and <a href="https://hub.docker.com/repository/docker/ovicrisan/contactformsamplepg" target="_blank">here</a>.<br />
<br />
Comments are welcome. Thanks.Ovi Crisanhttp://www.blogger.com/profile/11384935190005442742noreply@blogger.com0tag:blogger.com,1999:blog-5471705996745080901.post-84566716586973322442019-11-18T18:57:00.001-05:002019-11-18T18:57:36.874-05:00Seagate external hard driveBlack Friday came earlier this year for me with a new Seagate 6TB external hard drive, for all videos and books scattered of different computers and laptops I use, at home and at work. All good with it so far but it's formatted with NTFS which doesn't quite work on Mac OS. After a bit of digging I found out that Seagate offers a free version of <a href="https://www.seagate.com/support/downloads/item/ntfs-driver-for-mac-os-master-dl/">Paragon NTFS for Mac.</a> Installed and tested. Nice.Ovi Crisanhttp://www.blogger.com/profile/11384935190005442742noreply@blogger.com0tag:blogger.com,1999:blog-5471705996745080901.post-53690931900177445772019-11-07T20:11:00.004-05:002019-11-07T20:11:41.219-05:00ContactForm github projectIt's been a while since I wanted to post a personal project on GitHub, with few features I'm interested in: ASP.NET Core MVC and APIs, Azure DevOps, Azure Functions & AWS Lambda, as well as Docker images. Some other features will be covered in another project I'm working on, but let's keep that as a secret until available.<br />
<br />
The project I'm presenting now it's called <i>ContactForm</i> and is available at <a href="https://github.com/ovicrisan/ContactForm">github.com/OviCrisan/ContactForm</a> (see the link on the right side bar). It's meant for a simple contact form processing page, which works with both HTTP POST form data as well as REST API JSON, on the same endpoint (the root of deployed URL). There is more in the <i>readme.md</i> files from the project, with this diagram trying to explain different components:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://camo.githubusercontent.com/5782769a8d6aefb5474f960a0ab4291452defda1/68747470733a2f2f6f766963726973616e2e6769746875622e696f2f436f6e74616374466f726d2f696d616765732f636f6e74616374666f726d312e706e67" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="418" data-original-width="800" height="332" src="https://camo.githubusercontent.com/5782769a8d6aefb5474f960a0ab4291452defda1/68747470733a2f2f6f766963726973616e2e6769746875622e696f2f436f6e74616374466f726d2f696d616765732f636f6e74616374666f726d312e706e67" width="640" /></a></div>
The core of it is a .NET Standard 2.0 library deployed to NuGet.org (<a href="https://www.nuget.org/packages/OviCrisan.ContactForm/">nuget.org/packages/OviCrisan.ContactForm</a>), which then is used in <i>ContactForm.Web</i> (web app + web API), <i>ContactForm.AzFunc</i> (Azure Function) and <i>ContactForm.AWSLambda</i> (AWS Lambda function). Some libraries are using older versions just because AWS Lambda uses .NET Core 2.1, and also at the time of writing this Azure Functions 3.0 are in 'preview' mode.<br />
<br />
Depending on the settings in the config file or environment variables it enables email notification and/or webhook posting or REST API call. Also, optionally, you can enable Google reCAPTCHA v2 with visible checkbox. For this last option you need to register your own set of keys or use for testing Google provided samples, which you can find in the <i>readme</i> files in the project.<br />
<br />
The web application is also deployed as a Docker image at <a href="https://hub.docker.com/r/ovicrisan/contactformweb">hub.docker.com/r/OviCrisan/ContactFormWeb</a>, read more <a href="https://github.com/ovicrisan/ContactForm/blob/master/ContactForm.Web/readme.md">here</a>.<br />
<br />
The core library and web app have some unit testing projects, but very minimal (using XUnit). Also provided Azure DevOps <a href="https://github.com/ovicrisan/ContactForm/blob/master/ContactForm/azure-pipelines.yml">YAML file</a> for core library continuous integration. Some other additions will be added soon.<br />
<br />
Comments, suggestions and bugs reporting are welcome. Thanks in advance.Ovi Crisanhttp://www.blogger.com/profile/11384935190005442742noreply@blogger.com0tag:blogger.com,1999:blog-5471705996745080901.post-63908094603047146502019-11-06T22:59:00.000-05:002019-11-06T23:11:51.976-05:00PostgreSQL 12 on Windows 10I used previous versions of PostgreSQL, but I installed them with default Windows installer from the website which came with a Windows Service easy to start / stop. This last version 12 I installed with Chocolatey and I couldn't find any Windows Service to start.<br />
<br />
So, back to documentation and googling. First I create environment variable PGDATA pointing to a newly created data folder, like <i>C:\pgdata</i> (easier than specify that folder in parameters). Then from <i>C:\Program Files\PostgreSQL\12\bin</i> I ran:<br />
<br />
.\initdb C:\pgdata<br />
.\pg_ctl start<br />
.\createuser --interactive<br />
.\createdb test1<br />
<br />
Newly created user 'postgres' has the superuser role.<br />
<br />
Additionally, you can create other users with passwords to be used by the applications.<br />
<br />
Then, I prefer to use <a href="https://www.valentina-db.com/en/valentina-studio-overview" target="_blank">Valentina Studio</a> which integrates nicely with Postgres.Ovi Crisanhttp://www.blogger.com/profile/11384935190005442742noreply@blogger.com0tag:blogger.com,1999:blog-5471705996745080901.post-25379159497511552682019-11-04T15:56:00.001-05:002019-11-04T15:56:19.030-05:00Big Azure update todayThere are a <a href="https://azure.microsoft.com/en-us/updates/" target="_blank">lot of announcements</a> today from Microsoft Azure specially for <a href="https://www.microsoft.com/en-us/ignite" target="_blank">Ignite event</a>, some of most important ones in my opinion:<br />
<ul>
<li><a href="https://azure.microsoft.com/en-us/services/azure-arc/" target="_blank">Introducing Azure Arc</a> - a set of technologies that unlocks new hybrid scenarios for customers by bringing Azure services and management to any infrastructure.</li>
<li><a href="https://docs.microsoft.com/en-us/azure/data-share/" target="_blank">Azure Data Share</a> - a safe and secure service for sharing data with third-party organizations.</li>
<li><a href="https://azure.microsoft.com/en-us/updates/autopilot-mode-for-provisioned-throughput-is-now-in-preview/" target="_blank">Autopilot mode for provisioned throughput is now in preview</a> - Cosmos DB should be automatically scalable, otherwise what's the point? Plus new <a href="https://github.com/Azure/azure-cosmos-dotnet-v3" target="_blank">v3 SDK</a>.</li>
<li><a href="https://azure.microsoft.com/en-us/updates/sql-server-2019-is-now-generally-available/" target="_blank">SQL Server 2019 is now generally available</a></li>
<li><a href="https://docs.microsoft.com/en-us/azure/sql-database/sql-database-serverless" target="_blank">Azure SQL Database serverless</a> - pay the compute by the seconds of actual use + storage costs</li>
<li>Azure Functions - <a href="https://azure.microsoft.com/en-us/updates/net-core-3-support-in-azure-functions-now-in-preview/" target="_blank">v3 preview</a> + <a href="https://azure.microsoft.com/en-us/updates/powershell-support-in-azure-functions-is-now-generally-available/" target="_blank">PowerShell support</a> + <a href="https://azure.microsoft.com/en-us/updates/azure-functions-premium-plan-is-now-generally-available/" target="_blank">Premium plan GA</a> . I was working recently on a sample <a href="https://github.com/ovicrisan/ContactForm/tree/master/ContactForm.AzFunc" target="_blank">Azure Function project</a> but decided to use v2 instead of preview version v3, for few reasons (for instance, to reuse the code with <a href="https://github.com/ovicrisan/ContactForm/tree/master/ContactForm.AWSLambda" target="_blank">AWS Lambda function</a>).</li>
<li><a href="https://azure.microsoft.com/en-us/updates/azure-database-for-postgresql-hyperscale-citus-is-now-available/" target="_blank">Azure Database for PostgreSQL</a> - Hyperscale (Citus) is now available</li>
<li><a href="https://docs.microsoft.com/en-us/azure/aks/cluster-autoscaler" target="_blank">Azure Kubernetes Service (AKS) cluster autoscaler</a></li>
<li><a href="https://azure.microsoft.com/en-us/updates/azure-spot-vms-are-now-in-preview/" target="_blank">Azure Spot VMs are now in Preview</a></li>
<li><a href="https://azure.microsoft.com/en-us/updates/visual-studio-online-is-now-in-preview/" target="_blank">Visual Studio Online is now in preview</a> - VS in the browser, everywhere, cool!</li>
<li><a href="https://azure.microsoft.com/en-us/updates/new-azure-api-management-developer-portal-is-now-generally-available/" target="_blank">New Azure API Management developer portal is now generally available</a></li>
<li><a href="https://azure.microsoft.com/en-us/updates/secure-your-custom-domains-at-no-cost-with-app-service-managed-certificates-preview/" target="_blank">Free Transport Layer Security (TLS) for Azure App Service is now in preview</a></li>
<li><a href="https://azure.microsoft.com/en-us/updates/azure-monitor-prometheus-integration-is-now-generally-available/" target="_blank">Azure Monitor Prometheus integration is now generally available</a></li>
</ul>
<br />
<br />
<br />
<br />Ovi Crisanhttp://www.blogger.com/profile/11384935190005442742noreply@blogger.com0tag:blogger.com,1999:blog-5471705996745080901.post-40772390587476438902019-09-26T11:39:00.000-04:002019-09-26T14:20:31.862-04:00Conditionally added XML elementOn a project I'm working on we have to generate some XML documents with a pretty complex structure. In previous version we used <a href="https://docs.microsoft.com/en-us/dotnet/api/system.xml.xmldocument" target="_blank">XmlDocument</a>, but the code is pretty verbose, so I checked <a href="https://docs.microsoft.com/en-us/dotnet/api/system.xml.linq.xdocument" target="_blank">XDocument</a> alternative from Linq to XML.<br />
<div>
<br /></div>
<div>
This new solution works better (looks like is even faster), but I was looking for a simple solution to skip empty nodes. We didn't want <i><node></node></i> or <i><node /></i>.</div>
<div>
<br /></div>
<div>
So in the end I tried something like this:</div>
<div>
<blockquote class="tr_bq">
using System;<br />
using System.Linq;<br />
using System.Xml.Linq;<br />
namespace ConsoleApp1<br />
{<br />
class Program<br />
{<br />
static void Main(string[] args)<br />
{<br />
var b3 = string.Empty; // "3"<br />
XDocument x = new XDocument(<br />
new XDeclaration("1.0", "utf-8", null),<br />
new XElement("a",<br />
new XElement("b1", "1"),<br />
ElemString("b2", "2"),<br />
ElemString("b3", b3),<br />
new XElement("b4", string.Empty),<br />
new XElement("b5", null),<br />
ElemChildren("c", ElemString("c1", "11"), ElemString("c2", string.Empty)),<br />
ElemChildren("d", ElemString("d1", string.Empty), ElemString("d2", string.Empty))<br />
)<br />
);<br />
x.Save(Console.Out);<br />
Console.ReadKey();<br />
}<br />
static XElement ElemChildren(string name, params object[] children) {<br />
return children.Where( obj => obj != null).Any() ? new XElement(name, children) : null;<br />
}<br />
static XElement ElemString(string name, string val) {<br />
return string.IsNullOrEmpty(val) ? null : new XElement(name, val);<br />
}<br />
}<br />
}</blockquote>
</div>
<div>
which produces:</div>
<div>
<blockquote class="tr_bq">
<?xml version="1.0" encoding="utf-8"?><br />
<a><br />
<b1>1</b1><br />
<b2>2</b2><br />
<b4></b4><br />
<b5 /><br />
<c><br />
<c1>11</c1><br />
</c><br />
</a> </blockquote>
</div>
<div>
ElemChildren() was used to exclude a node having all children Null, while ElemString() is a simple ternary function (here's only for strings, most important part).<br />
Notice the difference between <b4></b4> and <b5 />. Also notice that node <d> is missing completely because of all Null children nodes.</div>
Ovi Crisanhttp://www.blogger.com/profile/11384935190005442742noreply@blogger.com0tag:blogger.com,1999:blog-5471705996745080901.post-18161329225626963722019-09-23T15:34:00.004-04:002019-09-23T15:36:40.443-04:00.NET Core 3.0 and .NET Core 3.1 LTSNew <a href="https://devblogs.microsoft.com/dotnet/announcing-net-core-3-0/" target="_blank">.NET Core 3.0</a> was just launched today at <a href="https://www.dotnetconf.net/" target="_blank">.NET Conf</a> but I also see that new LTS version is announced:<br />
<br />
<blockquote class="tr_bq">
.NET Core 3.0 is a ‘current’ release and will be superseded by .NET Core 3.1, targeted for November 2019. .NET Core 3.1 will be a long-term supported (LTS) release (supported for at least 3 years). We recommend that you adopt .NET Core 3.0 and then adopt 3.1. It’ll be very easy to upgrade.</blockquote>
Nice. Moving very fast, hard to catch up with all the new announced features.<br />
<br />
Also don't forget that .NET 2.2 will be retired at the end of this year: ".NET Core 2.2 will go EOL on 12/23"Ovi Crisanhttp://www.blogger.com/profile/11384935190005442742noreply@blogger.com0tag:blogger.com,1999:blog-5471705996745080901.post-21687278513767125382019-09-11T09:47:00.000-04:002019-09-11T09:47:20.861-04:00eShopOnWeb PR to allow basket items removalI did a <a href="https://github.com/dotnet-architecture/eShopOnWeb/pull/300" target="_blank">PR request</a> on <a href="https://github.com/ovicrisan/eShopOnWeb" target="_blank">forked</a> Microsoft's demo project <a href="https://github.com/dotnet-architecture/eShopOnWeb" target="_blank">eShopOnWeb</a> to allow basket items removal by setting the quantity to zero. See the <a href="https://github.com/dotnet-architecture/eShopOnWeb/pull/300/commits/70e009bda20734e726af9c4c78ee82b8aa86780e" target="_blank">commit 70e009b</a>.<br />
<br />
Also, added 2 more tests (a unit and another integration test) for new functionality. Plus another small fix in some unit testing async functions to return Task instead of void.<br />
<br />
This sample project is a good example of architectural principles, very well described in the eBook that comes with the project. I'm thinking to do some other contributions to this project, as coding exercises.<br />
<br />Ovi Crisanhttp://www.blogger.com/profile/11384935190005442742noreply@blogger.com1tag:blogger.com,1999:blog-5471705996745080901.post-59572220010898957762019-09-04T16:54:00.001-04:002019-09-04T16:54:49.766-04:00.NET Core 3.0Microsoft launched today <a href="https://dotnet.microsoft.com/download/dotnet-core/3.0" target="_blank">.NET Core 3.0 preview 9</a>, probably the last preview version before the official launch at <a href="https://www.dotnetconf.net/" target="_blank">.NET Conf</a>, on Sept. 23rd.<br />
<br />
They are also running <a href="https://www.dotnetconf.net/local-events" target="_blank">local events</a> for this launch, I already registered for one in Toronto, on Oct. 7th. See you there?Ovi Crisanhttp://www.blogger.com/profile/11384935190005442742noreply@blogger.com0tag:blogger.com,1999:blog-5471705996745080901.post-68406238161212165172019-06-26T20:13:00.001-04:002019-06-26T20:13:05.864-04:00Software Architecture for Developers by Simon BrownA book mainly addressed to developers, especially to those who want to switch roles to software architecture, in an agile environment.<br />
<br />
<a href="https://www.linkedin.com/pulse/software-architecture-developers-ovi-crisan">Read more on my LinkedIn article.</a><br />
<br />Ovi Crisanhttp://www.blogger.com/profile/11384935190005442742noreply@blogger.com1tag:blogger.com,1999:blog-5471705996745080901.post-32845667275763846842019-06-19T23:54:00.000-04:002019-06-19T23:54:02.306-04:00Designing Autonomous Teams and Services<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-BsF12qWrmTs/XQsDQ6yOPhI/AAAAAAAAAJU/ArNjBEclvnk-fhGvvN4g3HnstiQit8gJACLcBGAs/s1600/auto-teams.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="270" data-original-width="600" height="144" src="https://1.bp.blogspot.com/-BsF12qWrmTs/XQsDQ6yOPhI/AAAAAAAAAJU/ArNjBEclvnk-fhGvvN4g3HnstiQit8gJACLcBGAs/s320/auto-teams.png" width="320" /></a></div>
<br />
A review of <a href="https://www.oreilly.com/library/view/designing-autonomous-teams/9781491994320/"><i>Designing Autonomous Teams and Services</i> </a>book by Scott Millett and Nick Tune (O'Reilly, 2017)<br />
<br />
<a href="https://www.linkedin.com/pulse/designing-autonomous-teams-services-ovi-crisan">Read it on my LinkedIn profile article</a>.<br />
<br />Ovi Crisanhttp://www.blogger.com/profile/11384935190005442742noreply@blogger.com2