<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Juan</title>
    <description>The latest articles on DEV Community by Juan (@qjuanp).</description>
    <link>https://dev.to/qjuanp</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F15682%2Fae35f2f9-15cb-4fe3-89a7-3cb872357664.jpeg</url>
      <title>DEV Community: Juan</title>
      <link>https://dev.to/qjuanp</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/qjuanp"/>
    <language>en</language>
    <item>
      <title>Recommended podcasts</title>
      <dc:creator>Juan</dc:creator>
      <pubDate>Fri, 03 Jun 2022 00:00:00 +0000</pubDate>
      <link>https://dev.to/qjuanp/recommended-podcasts-1on4</link>
      <guid>https://dev.to/qjuanp/recommended-podcasts-1on4</guid>
      <description>&lt;p&gt;Here is the non-requested podcast lists around Software Development.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Podcast&lt;/th&gt;
&lt;th&gt;Link&lt;/th&gt;
&lt;th&gt;Review&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Maintainable&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.maintainable.fm"&gt;maintainable.fm&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Conversations with developers and engineers around maintain and evolve software. Important topic of you consider committed code as legacy code!&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CaSE: Conversations about Software Engineering&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.case-podcast.org"&gt;vase-podcast.org&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Interviewing developers and architects about software engineering and development.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Software Engineering Radio&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.se-radio.net"&gt;se-radio.net&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Engineers talking about their experience around different topics around building software.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Soft Skills Engineering&lt;/td&gt;
&lt;td&gt;&lt;a href="https://softskill%C3%B1s.audio"&gt;softskills.audio&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Not everything is code and tools when we talk about software development.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Developer tea&lt;/td&gt;
&lt;td&gt;&lt;a href="https://developertea.com"&gt;developertea.com&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;This podcast focus as well in the human part of develop software.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dev Discussions&lt;/td&gt;
&lt;td&gt;&lt;a href="https://podcasts.apple.com/ie/podcast/dev-discussions/id954824483"&gt;Apple podcast&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Conversations around topics around software development, techniques and patterns.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;My DMs on twitter are open &lt;a href="https://twitter.com/qjuanp"&gt;@qjuanp&lt;/a&gt; feel free to recommend me more podcasts! I’m looking for comedy (international and local Irish comedy for foreigners) and interesting stories in this format. Thanks!&lt;/p&gt;

</description>
      <category>bookmarks</category>
      <category>podcast</category>
    </item>
    <item>
      <title>Methodology vs Framework</title>
      <dc:creator>Juan</dc:creator>
      <pubDate>Tue, 31 May 2022 00:00:00 +0000</pubDate>
      <link>https://dev.to/qjuanp/methodology-vs-framework-132f</link>
      <guid>https://dev.to/qjuanp/methodology-vs-framework-132f</guid>
      <description>&lt;p&gt;Just trying to explain this two concepts that could help driving conversations at architecture level since there is always a situation in during the design where you will find using them.&lt;/p&gt;

&lt;p&gt;So, first of all, they are not synonyms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Methodology
&lt;/h2&gt;

&lt;p&gt;This is a common used concepts among academics. For dissertations, the methodology explains how a particular conclusion was reached. A methodology express the procedures, methods, principles and rules under a particular discipline &lt;a href="https://en.wikipedia.org/wiki/Methodology"&gt;[1]&lt;/a&gt; that will lead you to an specific result, in terms of a thesis, the conclusion reached.&lt;/p&gt;

&lt;p&gt;And moving that concept into the software development scope &lt;a href="https://en.wikipedia.org/wiki/Software_development_process"&gt;[2]&lt;/a&gt;, a methodology defines the process and the set of specific deliverables and artifacts that are needed to develop and maintain applications during its lifecycle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Framework
&lt;/h2&gt;

&lt;p&gt;It’s basically a tool set or a set of methods that can be applied separately or all the same time, the process to apply each method might or might not defined, but, is not essential for the usage of each tool.&lt;/p&gt;

&lt;p&gt;In software &lt;a href="https://en.wikipedia.org/wiki/Software_framework"&gt;[3]&lt;/a&gt; we use the term frameworks as well, frameworks like .NET (yes, dotnet core is still a framework), Java EE, Spring, etc, define tools and components that can help you to build and deploy applications.&lt;/p&gt;

&lt;p&gt;In Project Management for example, PM Book can be identified as framework, since it defines a set of methods to be used in projects, but it not defines the procedure to combine each method.&lt;/p&gt;

&lt;h2&gt;
  
  
  Core differences
&lt;/h2&gt;

&lt;p&gt;In conclusion, a methodology defines what to deliver, how to create those deliverables and the logical order to do so, meanwhile a framework only defines what you can do.&lt;/p&gt;

&lt;p&gt;That is why you can use 2 different frameworks to produce something new, for example, in software you could use Spring of top of Java EE, or Scrum with a Critical Path Method from the PM BoK (r).&lt;/p&gt;

&lt;h2&gt;
  
  
  Some examples
&lt;/h2&gt;

&lt;p&gt;Now that we know the differences, we can categorize the following practices and software components under each category.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scrum is a framework&lt;/li&gt;
&lt;li&gt;Agile is a framework&lt;/li&gt;
&lt;li&gt;Angular is a framework&lt;/li&gt;
&lt;li&gt;Ionic is a framework&lt;/li&gt;
&lt;li&gt;react it’s not a framework nor a methodology…&lt;/li&gt;
&lt;li&gt;Nodejs it’s not a framework nor a methodology…&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In software we use a lot frameworks, since we need to adapt the principles, deliverables, components to specific contexts.&lt;/p&gt;

&lt;p&gt;You can &lt;a href="https://www.projectmanagement.com/contentPages/article.cfm?ID=278600&amp;amp;thisPageURL=/articles/278600/why-you-re-confusing-frameworks-with-methodologies#_=_"&gt;check the post&lt;/a&gt; made by Michael Wood where he digs more in other Frameworks and methodologies used around technology projects and organizations.&lt;/p&gt;

</description>
      <category>concepts</category>
      <category>architecture</category>
      <category>productdevelopment</category>
      <category>softwaredesign</category>
    </item>
    <item>
      <title>VSCode-Java Maven configuration error</title>
      <dc:creator>Juan</dc:creator>
      <pubDate>Mon, 10 Jan 2022 00:00:00 +0000</pubDate>
      <link>https://dev.to/qjuanp/vscode-java-maven-configuration-error-2n0j</link>
      <guid>https://dev.to/qjuanp/vscode-java-maven-configuration-error-2n0j</guid>
      <description>&lt;p&gt;There is no day that I not face a “funny” error developing in Java, saying that, it’s not my intention generate drama nor a new whole discussion Java vs The world…. this error is merely product of my ignorance in java and the composability you could find in this development ecosystem (coff coff Msft!).&lt;/p&gt;

&lt;p&gt;Joke aside, I found myself in a “particular” scenario:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When I run the cli command &lt;code&gt;mvn clean compile&lt;/code&gt; project simply compile perfectly!, even the tests were running without a problem. But, when I opened up the project in a VSCode, the compiler went crazy and it was just saying that the project has a ton or compilation errors, errors like:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;“Failed to read artifact descriptor for…”&lt;/li&gt;
&lt;li&gt;“Missing artifact…”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;VSCode-Java uses under the hood the same tools, java and maven, to verify the sources and bring us information during development, so, how can be possible get two different results if, under the hood, are basically the same tooling?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This error can come up with certain packages available in &lt;strong&gt;private repositories&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The problem is basically that VSCode-Java/Maven tool is not able to find the default settings that are commonly stored in &lt;code&gt;~/.m2/settings.xml&lt;/code&gt; or &lt;code&gt;%USER_PROFILE%\.m2\settings.xml&lt;/code&gt; where the private repositories for maven are configured.&lt;/p&gt;

&lt;p&gt;This can be specified using the VSCode setting entry:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"java.configuration.maven.userSettings": "C:\\Users\\&amp;lt;UserName&amp;gt;\\.m2\\setttings.xml",&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Or pointing to the specific settings.xml location that you are using for private repos.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hope that it helps!&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/redhat-developer/vscode-java/issues/1232"&gt;redhat-developer/vscode-java#1232&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/redhat-developer/vscode-java/issues/1365"&gt;redhat-developer/vscode-java#1365&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>notes</category>
      <category>development</category>
      <category>configuration</category>
      <category>java</category>
    </item>
    <item>
      <title>Git - Deal with rejected changes over protected branches</title>
      <dc:creator>Juan</dc:creator>
      <pubDate>Mon, 27 Sep 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/qjuanp/git-deal-with-rejected-changes-over-protected-branches-10i8</link>
      <guid>https://dev.to/qjuanp/git-deal-with-rejected-changes-over-protected-branches-10i8</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QSL_TgJi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://qjuanp.dev/assets/2021-09-27-git-deal-with-rejected-changes-over-protected-branches/state.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QSL_TgJi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://qjuanp.dev/assets/2021-09-27-git-deal-with-rejected-changes-over-protected-branches/state.png" alt="This could be your state, having a commit out of sync because is rejected by git remote" width="401" height="121"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario:&lt;/strong&gt; main(&lt;a href="https://github.com/github/renaming%20(Renaming%20the%20default%20branch%20from%20master%20-%20extended%20expkanation%20by%20Github%20about%20why%20rename%20master%20as%20main%20in%20all%20repos)"&gt;*&lt;/a&gt;) integration branch rejects changes when try to pushing into remote repository. This is a common practice to follow Gitflow (or other branching strategies) to enforce merge reviews into the into the main branch.&lt;/p&gt;

&lt;p&gt;So, how to push correctly your changes into main integration branch?&lt;/p&gt;

&lt;p&gt;Summary:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a feature branch&lt;/li&gt;
&lt;li&gt;Reset your local main integration branch and sync up with remote main branch&lt;/li&gt;
&lt;li&gt;Push your feature branch and create a Pull Request&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Create a feature branch
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Mr3z6WKt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://qjuanp.dev/assets/2021-09-27-git-deal-with-rejected-changes-over-protected-branches/step-1-create-branch.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Mr3z6WKt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://qjuanp.dev/assets/2021-09-27-git-deal-with-rejected-changes-over-protected-branches/step-1-create-branch.png" alt="create a feature branch" width="531" height="229"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create a feature branch from your main integration branch, remember that branches are just named pointers to actual commits, so, new branch will be pointing out to your latest changes, which are the ones you’re trying to push correctly into the integration branch.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git checkout -b [feature-branch-name]&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Remember to follow your defined naming conventions to name the new feature branch.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Reset main
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wgCIp9sw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://qjuanp.dev/assets/2021-09-27-git-deal-with-rejected-changes-over-protected-branches/step-2-reset-main.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wgCIp9sw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://qjuanp.dev/assets/2021-09-27-git-deal-with-rejected-changes-over-protected-branches/step-2-reset-main.png" alt="Reset main branch" width="531" height="229"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s move the local main branch pointer to the same commit that remote branch is referencing.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In this example we assume that is just one commit behind the last commit, in that case we just need to run:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;git reset --hard HEAD~1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reset will move the pointer&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--hard&lt;/code&gt; just move the pointer, discard all the changes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;HEAD~1&lt;/code&gt; one commit before current HEAD pointer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result is something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VuueJ3Qo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://qjuanp.dev/assets/2021-09-27-git-deal-with-rejected-changes-over-protected-branches/step-2-result.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VuueJ3Qo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://qjuanp.dev/assets/2021-09-27-git-deal-with-rejected-changes-over-protected-branches/step-2-result.png" alt="Result of resetting main branch" width="501" height="121"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Push your feature branch and create a PR
&lt;/h2&gt;

&lt;p&gt;Now you can push your changes under the new branch:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git push origin [feature-branch]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And after that you will be able to create a PR to merge your changes with the main integration branch.&lt;/p&gt;

</description>
      <category>notes</category>
      <category>git</category>
      <category>branching</category>
    </item>
    <item>
      <title>Introduction to Sets in Rego</title>
      <dc:creator>Juan</dc:creator>
      <pubDate>Sun, 25 Apr 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/qjuanp/introduction-to-sets-in-rego-5fj7</link>
      <guid>https://dev.to/qjuanp/introduction-to-sets-in-rego-5fj7</guid>
      <description>&lt;p&gt;&lt;a href="https://www.openpolicyagent.org/docs/latest/#rego"&gt;Rego&lt;/a&gt; is a declarative language used to define policies in &lt;a href="https://www.openpolicyagent.org/"&gt;Open Policy Agent (OPA)&lt;/a&gt;. This declarative language works defining queries that behaves like assertions over structured data stored in OPA.&lt;/p&gt;

&lt;p&gt;In other words, we could said that OPA is the engine that interprets and evaluate policies written in Rego.&lt;/p&gt;

&lt;p&gt;But, what is a Policy? an over-simplified analogy could be that a policy is a pre-condition: “a condition or predicate that must always be true prior the execution of something” &lt;a href="https://en.wikipedia.org/wiki/Precondition"&gt;#&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;An example of a policy could be:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Users can only buy if its profile has an address and a phone number&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We could identify here a concrete action that is: “buy”, but before that action occurs the following pre-conditions should be meet:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User profile must have an address&lt;/li&gt;
&lt;li&gt;User profile must have a phone number&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this particular case, rego assertions needs only to verify that a couple of fields contains some value, so, the final policy in rego looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;default profile_completed = false

profile_completed {
    count(input.phone) != 0
    count(input.address) != 0
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;sup&gt;see this example in action ▶️ &lt;a href="https://play.openpolicyagent.org/p/4k0TZcT1hy"&gt;&lt;/a&gt;&lt;a href="https://play.openpolicyagent.org/p/4k0TZcT1hy"&gt;https://play.openpolicyagent.org/p/4k0TZcT1hy&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;Nevertheless, there are cases where expressions get more interesting, one of those cases is when you have to compare data collections with rego assertions.&lt;/p&gt;

&lt;p&gt;One example of this type of policies is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Only authorized roles assigned to an user can access the content&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Rego collection data types
&lt;/h2&gt;

&lt;p&gt;Collections (&lt;a href="https://www.openpolicyagent.org/docs/latest/policy-language/#composite-values"&gt;Composite values&lt;/a&gt;) in rego come in different flavors, has different built-in functions and syntactic sugar.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Object/Dictionary/Map: key-valued collections &amp;gt; we will talk in another post about particular data type.&lt;/li&gt;
&lt;li&gt;Array: indexed collection&lt;/li&gt;
&lt;li&gt;Set: non-indexed/unordered collections of unique values&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you may noticed, there are substantial differences between Sets and Arrays, despite they use same representation when is serialized into JSON.&lt;/p&gt;

&lt;p&gt;For the specific scenario that we are evaluating, values in the collection are the important ones, not so much where are they located at, which means, Sets will suit perfectly to write a policy and when you dig into built-in operations you will notice why too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sets in Rego
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Declaring sets
&lt;/h3&gt;

&lt;p&gt;First thing first, how does it look a &lt;a href="https://www.openpolicyagent.org/docs/latest/policy-language/#sets"&gt;set&lt;/a&gt; in rego?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Set of primitive types
s := {"this", "is", "a", "set"}

s := {8,2,26}

// Set of complex types

s := {
    {"country":"🇨🇴"},
    {"country":"🇮🇪"}
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sets and arrays share a similar syntaxis, although Arrays use square brackets &lt;code&gt;[...]&lt;/code&gt; and Sets use curly brackets &lt;code&gt;{...}&lt;/code&gt;. Yes, objects in rego use curly brackets as well, but remember that objects are key-value collections.&lt;/p&gt;

&lt;h3&gt;
  
  
  Equality
&lt;/h3&gt;

&lt;p&gt;Here is where sets start to look interesting! since it contains only unique values the equality comparison is pretty simple&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{1,2,3} == {3,1,2} // -&amp;gt; true

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;[2] Example taken from official documentation.&lt;/p&gt;

&lt;p&gt;And yes, when you declare a set it just store unique values&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;s:= {1,1,2,2,3,3}
s == {3,2,1} // -&amp;gt; true

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Projection
&lt;/h3&gt;

&lt;p&gt;You could create new sets based on subqueries using &lt;a href="https://www.openpolicyagent.org/docs/latest/policy-language/#set-comprehensions"&gt;“Comprehension”&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;comp := { head | body ; condition&amp;lt;optional&amp;gt; } 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tip: You could use comprehensions to create other Composite values like objects and arrays, structure is the same (head, body, condition), just take a look of specific syntaxis for each type.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;head → item to be taken for the new set.&lt;/li&gt;
&lt;li&gt;body → expression indicating where to extract the item.&lt;/li&gt;
&lt;li&gt;condition → if condition result is &lt;code&gt;true&lt;/code&gt; the item will be added into the resulting set, otherwise is discarded.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Intersection
&lt;/h2&gt;

&lt;p&gt;When you have 2 sets, you could get the intersection from both sets using the binary operator &lt;code&gt;&amp;amp;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;french := { 
    "🇳🇪 Niger", 
    "🇨🇲 Cameroon", 
    "🇬🇳 Guinea", 
    "🇨🇦 Canada" 
}

english := { 
    "🇨🇲 Cameroon", 
    "🇮🇪 Ireland", 
    "🇳🇬 Nigeria", 
    "🇿🇦 South Africa", 
    "🇨🇦 Canada" 
}

english_and_french := english &amp;amp; french ## --&amp;gt; { "🇨🇲 Cameroon", "🇨🇦 Canada" }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This intersection is precisely what we are looking to define a policy around the scenario proposed, let’s take a look&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--i1kZYBn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://qjuanp.dev/assets/2021-04-25-introduction-sets-rego-open-policy-agent/intersection.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i1kZYBn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://qjuanp.dev/assets/2021-04-25-introduction-sets-rego-open-policy-agent/intersection.png" alt="Intersection between user assigned roles and allowed roles list - Venn Diagram" width="371" height="121"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s say for example that we have part of the content (what ever it is) and that content could be accessible for System Administrators and Publishers, so, the allowed set of roles could look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;allowed_roles := { "admin", "publisher" }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we are getting from the actual system that is validating content access against OPA the list of roles assigned to the logged user, so, we receive the following JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "username": "qjuanp",
    "roles": ["writter", "publisher", "developer"]
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Knowing what is a set and how to use the intersection operation we could define the policy in rego as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;default allow = false # By default is not allowed

allow {
    user_roles := { role | role := input.roles[_] } # user roles came as an array, so let's create a set version
    user_allowed_roles := user_roles &amp;amp; allowed_roles
    count(user_allowed_roles) &amp;gt; 0 # final result of the alternative rule set `allow`
}

allowed_roles := { "admin", "publisher" }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;sup&gt;see this example in action ▶️ &lt;a href="https://play.openpolicyagent.org/p/gjMYmbDg4C"&gt;&lt;/a&gt;&lt;a href="https://play.openpolicyagent.org/p/gjMYmbDg4C"&gt;https://play.openpolicyagent.org/p/gjMYmbDg4C&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;It’s important to transform arrays into sets to use properly sets operations, otherwise OPA won’t tell you that there is an error and instead is going to use the unique values present in the array → indexes, which is going to mislead the rego policy evaluation.&lt;/p&gt;

&lt;p&gt;Alongside with intersection there are two more interesting &lt;a href="https://www.openpolicyagent.org/docs/latest/policy-reference/#sets-2"&gt;bult-in operations&lt;/a&gt; to work with sets: Minus (left join) and union, and other syntactic sugar “Rule Sets”, but I will write about them in future notes, stay tuned.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;if you want to learn more in general about Rego, I’d recommend start with &lt;a href="https://blog.openpolicyagent.org/rego-design-principle-1-syntax-should-reflect-real-world-policies-e1a801ab8bfb"&gt;this post&lt;/a&gt;:&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;a href="https://github.com/qjuanp/qjuanp.github.io/issues/new?assignees=qjuanp&amp;amp;labels=review&amp;amp;template=post-feedback.md&amp;amp;title=%5Bpost+feedback%5D"&gt;👉 make a suggestion&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you want to help me with this post redaction don’t hesitate on create an issue in the GitHub repo where it’s hosted, use this link to get you there, and thanks!&lt;/p&gt;
&lt;/blockquote&gt;




</description>
      <category>devops</category>
      <category>opa</category>
      <category>rego</category>
      <category>sets</category>
    </item>
  </channel>
</rss>
