From 8a3128a65610fa0b9899a2d693d7e792f519e79b Mon Sep 17 00:00:00 2001
From: Jinah Yun-Mitchell
Date: Tue, 12 Nov 2024 10:13:39 -0600
Subject: [PATCH] ENDOC-816 remove blog & menu edits
---
vuepress/docs/.vuepress/config.js | 14 +-
.../2022-04-20-why-is-blogging-important.md | 60 ----
...022-04-22-new-with-the-entando7-release.md | 44 ---
.../2022-05-03-using-react-to-create-mfe.md | 239 --------------
.../2022-06-15-using-vue-to-create-mfe.md | 235 --------------
.../docs/_posts/2022-06-15-what-is-the-hub.md | 89 ------
.../2022-07-12-update-on-k8s-support.md | 25 --
.../2022-08-11-entando7-release-overview.md | 102 ------
.../2022-09-19-update-on-k8s-support.md | 24 --
.../2022-12-19-explore-docker-bundles.md | 301 ------------------
...2023-01-26-composable-apps-security-k8s.md | 34 --
...ng-business-based-autonomous-components.md | 192 -----------
vuepress/docs/_posts/2023-08-04-k8s-126.md | 18 --
...-09-install-entando-with-docker-desktop.md | 107 -------
vuepress/docs/_posts/2023-08-14-streamlit.md | 254 ---------------
.../2023-08-17-spring-boot-websockets.md | 293 -----------------
vuepress/docs/_posts/README.md | 1 +
vuepress/docs/_posts/images/2022-04-22.png | Bin 105828 -> 0 bytes
.../docs/_posts/images/2022-05-03-image1.png | Bin 35524 -> 0 bytes
.../docs/_posts/images/2022-05-03-image2.png | Bin 70255 -> 0 bytes
.../docs/_posts/images/2022-05-03-image3.png | Bin 57023 -> 0 bytes
.../docs/_posts/images/2022-06-15-aviard1.png | Bin 111198 -> 0 bytes
.../docs/_posts/images/2022-06-15-aviard2.png | Bin 88905 -> 0 bytes
.../docs/_posts/images/2022-06-15-aviard3.png | Bin 159627 -> 0 bytes
.../docs/_posts/images/2022-06-15-image1.png | Bin 85121 -> 0 bytes
.../docs/_posts/images/2022-06-15-image2.png | Bin 18584 -> 0 bytes
.../docs/_posts/images/2022-06-15-image3.png | Bin 97545 -> 0 bytes
.../docs/_posts/images/2022-06-15-image4.png | Bin 38559 -> 0 bytes
.../docs/_posts/images/2022-06-15-image5.png | Bin 20265 -> 0 bytes
.../docs/_posts/images/2022-06-15-image6.png | Bin 166962 -> 0 bytes
.../docs/_posts/images/2022-06-15-image7.png | Bin 190379 -> 0 bytes
.../images/2022-08-11-acp-capabilities.png | Bin 94481 -> 0 bytes
.../_posts/images/2022-08-11-acp-process.png | Bin 158466 -> 0 bytes
.../_posts/images/2022-08-11-publishing.png | Bin 88537 -> 0 bytes
.../docs/_posts/images/2022-12-19-image1.png | Bin 67136 -> 0 bytes
.../docs/_posts/images/2022-12-19-image10.png | Bin 62621 -> 0 bytes
.../docs/_posts/images/2022-12-19-image2.png | Bin 20474 -> 0 bytes
.../docs/_posts/images/2022-12-19-image3.png | Bin 88537 -> 0 bytes
.../docs/_posts/images/2022-12-19-image4.png | Bin 89211 -> 0 bytes
.../docs/_posts/images/2022-12-19-image5.png | Bin 107934 -> 0 bytes
.../docs/_posts/images/2022-12-19-image6.png | Bin 79694 -> 0 bytes
.../docs/_posts/images/2022-12-19-image7.png | Bin 82230 -> 0 bytes
.../docs/_posts/images/2022-12-19-image8.png | Bin 25760 -> 0 bytes
.../docs/_posts/images/2022-12-19-image9.png | Bin 74217 -> 0 bytes
.../docs/_posts/images/2023-01-26-process.png | Bin 71216 -> 0 bytes
vuepress/docs/_posts/images/2023-01-26.png | Bin 63078 -> 0 bytes
.../docs/_posts/images/2023-03-17-image1.png | Bin 2959 -> 0 bytes
.../docs/_posts/images/2023-03-17-image2.png | Bin 22876 -> 0 bytes
.../docs/_posts/images/2023-03-17-image3.png | Bin 47718 -> 0 bytes
.../2023-08-15-streamlit-in-entando.png | Bin 30448 -> 0 bytes
.../_posts/images/2023-08-17-spring-init.png | Bin 67514 -> 0 bytes
.../images/2023-08-17-stomp-local-test.png | Bin 129315 -> 0 bytes
52 files changed, 4 insertions(+), 2028 deletions(-)
delete mode 100644 vuepress/docs/_posts/2022-04-20-why-is-blogging-important.md
delete mode 100644 vuepress/docs/_posts/2022-04-22-new-with-the-entando7-release.md
delete mode 100644 vuepress/docs/_posts/2022-05-03-using-react-to-create-mfe.md
delete mode 100644 vuepress/docs/_posts/2022-06-15-using-vue-to-create-mfe.md
delete mode 100644 vuepress/docs/_posts/2022-06-15-what-is-the-hub.md
delete mode 100644 vuepress/docs/_posts/2022-07-12-update-on-k8s-support.md
delete mode 100644 vuepress/docs/_posts/2022-08-11-entando7-release-overview.md
delete mode 100644 vuepress/docs/_posts/2022-09-19-update-on-k8s-support.md
delete mode 100644 vuepress/docs/_posts/2022-12-19-explore-docker-bundles.md
delete mode 100644 vuepress/docs/_posts/2023-01-26-composable-apps-security-k8s.md
delete mode 100644 vuepress/docs/_posts/2023-03-17-building-business-based-autonomous-components.md
delete mode 100644 vuepress/docs/_posts/2023-08-04-k8s-126.md
delete mode 100644 vuepress/docs/_posts/2023-08-09-install-entando-with-docker-desktop.md
delete mode 100644 vuepress/docs/_posts/2023-08-14-streamlit.md
delete mode 100644 vuepress/docs/_posts/2023-08-17-spring-boot-websockets.md
create mode 100644 vuepress/docs/_posts/README.md
delete mode 100644 vuepress/docs/_posts/images/2022-04-22.png
delete mode 100644 vuepress/docs/_posts/images/2022-05-03-image1.png
delete mode 100644 vuepress/docs/_posts/images/2022-05-03-image2.png
delete mode 100644 vuepress/docs/_posts/images/2022-05-03-image3.png
delete mode 100644 vuepress/docs/_posts/images/2022-06-15-aviard1.png
delete mode 100644 vuepress/docs/_posts/images/2022-06-15-aviard2.png
delete mode 100644 vuepress/docs/_posts/images/2022-06-15-aviard3.png
delete mode 100644 vuepress/docs/_posts/images/2022-06-15-image1.png
delete mode 100644 vuepress/docs/_posts/images/2022-06-15-image2.png
delete mode 100644 vuepress/docs/_posts/images/2022-06-15-image3.png
delete mode 100644 vuepress/docs/_posts/images/2022-06-15-image4.png
delete mode 100644 vuepress/docs/_posts/images/2022-06-15-image5.png
delete mode 100644 vuepress/docs/_posts/images/2022-06-15-image6.png
delete mode 100644 vuepress/docs/_posts/images/2022-06-15-image7.png
delete mode 100644 vuepress/docs/_posts/images/2022-08-11-acp-capabilities.png
delete mode 100644 vuepress/docs/_posts/images/2022-08-11-acp-process.png
delete mode 100644 vuepress/docs/_posts/images/2022-08-11-publishing.png
delete mode 100644 vuepress/docs/_posts/images/2022-12-19-image1.png
delete mode 100644 vuepress/docs/_posts/images/2022-12-19-image10.png
delete mode 100644 vuepress/docs/_posts/images/2022-12-19-image2.png
delete mode 100644 vuepress/docs/_posts/images/2022-12-19-image3.png
delete mode 100644 vuepress/docs/_posts/images/2022-12-19-image4.png
delete mode 100644 vuepress/docs/_posts/images/2022-12-19-image5.png
delete mode 100644 vuepress/docs/_posts/images/2022-12-19-image6.png
delete mode 100644 vuepress/docs/_posts/images/2022-12-19-image7.png
delete mode 100644 vuepress/docs/_posts/images/2022-12-19-image8.png
delete mode 100644 vuepress/docs/_posts/images/2022-12-19-image9.png
delete mode 100644 vuepress/docs/_posts/images/2023-01-26-process.png
delete mode 100644 vuepress/docs/_posts/images/2023-01-26.png
delete mode 100644 vuepress/docs/_posts/images/2023-03-17-image1.png
delete mode 100644 vuepress/docs/_posts/images/2023-03-17-image2.png
delete mode 100644 vuepress/docs/_posts/images/2023-03-17-image3.png
delete mode 100644 vuepress/docs/_posts/images/2023-08-15-streamlit-in-entando.png
delete mode 100644 vuepress/docs/_posts/images/2023-08-17-spring-init.png
delete mode 100644 vuepress/docs/_posts/images/2023-08-17-stomp-local-test.png
diff --git a/vuepress/docs/.vuepress/config.js b/vuepress/docs/.vuepress/config.js
index 5ef8ba61db..b8b6a1568f 100644
--- a/vuepress/docs/.vuepress/config.js
+++ b/vuepress/docs/.vuepress/config.js
@@ -107,19 +107,12 @@ module.exports = {
type: 'links',
link: 'https://entando.com/'
},
- {
- text: 'Support',
- type: 'links',
- link: 'https://entando.com/en/services.page'
- },
{
text: 'Resources',
type: 'links',
items: [
{text: 'News', link: 'https://www.entando.com/page/en/news_and_press'},
- {text: 'Press Releases', link: 'https://entando.com/page/en/news_and_press?metadata_category_frame9=pressrelease'},
- {text: 'Press Kit', link: 'https://www.entando.com/page/en/press-kit'},
- {text: 'Webinars & Events', link: 'https://entando.com/page/en/webinars'},
+ {text: 'Press Releases', link: 'https://entando.com/entando-insights/press-release/'},
]
},
{
@@ -129,7 +122,6 @@ module.exports = {
{text: 'Getting Started', link: '/'},
{text: 'Docs', link: '/docs/'},
{text: 'Tutorials', link: '/tutorials/'},
- {text: 'Blog', link: '/blog/'},
{text: 'Slack', link: 'https://entandocommunity.slack.com/'},
{text: 'Forum', link: 'https://forum.entando.com'},
]
@@ -145,13 +137,13 @@ module.exports = {
{text: 'Docs', link: '/v7.3/docs/', target: '_self'},
{text: 'Tutorials', link: '/v7.3/tutorials/', target: '_self'},
{text: 'Forum', link: 'https://forum.entando.com'},
- {text: 'Blog', link: '/blog/'},
+
],
secondaryNav: [
{text: 'Docs', link: 'javascript:Entando.versionedLink("/docs");', target: '_self'},
{text: 'Tutorials', link: 'javascript:Entando.versionedLink("/tutorials");', target: '_self'},
{text: 'Forum', link: 'https://forum.entando.com'},
- {text: 'Blog', link: '/blog/'},
+
],
serviceWorker: {
updatePopup: true
diff --git a/vuepress/docs/_posts/2022-04-20-why-is-blogging-important.md b/vuepress/docs/_posts/2022-04-20-why-is-blogging-important.md
deleted file mode 100644
index 3ae87dbcce..0000000000
--- a/vuepress/docs/_posts/2022-04-20-why-is-blogging-important.md
+++ /dev/null
@@ -1,60 +0,0 @@
----
-author: Sohini Pattanayak
-date: 2022-04-20
-summary: Technical blogging is very important for modern developers, as it can not only help developers learn and grow but also help other people to learn from them. At the same time, documenting our learnings and experiences in the form of a blog is a very good practice for a developer in the IT industry. Through this blog, you'll figure out why it is so important to write technical blogs and also how you can get started with it.
-tags:
-- Developer Topics
-- Community
-title: Why is technical blogging so important?
----
-
-
All the learning that we gather together defines our knowledge. And when we put this knowledge into writing, providing direction, instruction, explanation, and empathy, we call it technical blogging.
-
-
But, why do we have to do this?
-
-
If we look at it from our own perspective, it's really helpful for us to grow as individuals. Documenting our learning process in a particular subject, in one place, in a complete manner is, first of all, self-help! There are two benefits to it:
-
-
-
Our storytelling capability develops and improves with time.
-
When we need to work on that particular subject, even after 5 years, the blogs we wrote help us stay up to date on the subject.
-
-
-
What, apart from these?
-
-
If you are someone who wishes to be around a technical community or a network of people, technical blogging is so your thing!
-
-
One technical blog can help many learn and grow, just as you grow personally. After all, we look for blogs when we try to learn something new. So, we can definitely be one of those bloggers whose writings are read by others as they try to learn something new.
-
-
But, what if you suffer from imposter syndrome?
-
-
"What if I am not proficient enough to write a blog? What if I don't have the skills to do it? What if I am not knowledgeable enough?"
-
-
Well, you don't need to be a pro in order to write a blog. If you're a very keen learner, you can always use your learnings to start writing blogs.
-
-
And whatever we learn is our knowledge. Hence, each one of us is absolutely qualified to write technical blogs.
-
-
Let's explore a few things we can use as best practices while writing blogs:
-
-
-
Always define key points before starting a blog. (These can also be goal statements.)
-
Dedicate each paragraph to a particular topic/area.
-
Make sure you are writing with your target audience in mind.
-
Create engaging sentences at the beginning of each paragraph to develop interest.
-
Break lengthy sentences into shorter ones.
-
Break up big ideas into smaller sections, with short paragraphs.
-
Use bullet points to explain agendas/steps.
-
When working with an in-depth technical subject, use flow diagrams to explain processes.
-
Be empathetic while you write. Express how you feel; don't be afraid to show your emotions in the writing. This will keep it from sounding like a dry step-by-step manual.
-
Use a tool to check spelling mistakes, nouns, pronouns, adjectives, etc.
-
-
-
-
These are the steps I try to follow when I am writing blogs. The best thing about writing blogs continuously is that your writing improves every time. And that is learning too.
-
-
To wrap up, it is not really hard to write a technical blog. The very first thing you really need to do is get started. And slowly, the quality of your writing and content will improve over time. Believe in your capabilities and write everything you can to best explain your content! The blogs you write can help many other people while satisfying your own curiosity and learning goals. It is mutually beneficial, for you and the audience you're writing the blog for.
-
-
That's all for this blog. I hope this was useful for you. Please feel free to drop your thoughts in the comment section below.
\ No newline at end of file
diff --git a/vuepress/docs/_posts/2022-04-22-new-with-the-entando7-release.md b/vuepress/docs/_posts/2022-04-22-new-with-the-entando7-release.md
deleted file mode 100644
index 35cf43694c..0000000000
--- a/vuepress/docs/_posts/2022-04-22-new-with-the-entando7-release.md
+++ /dev/null
@@ -1,44 +0,0 @@
----
-author: Sohini Pattanayak
-date: 2022-04-22
-summary: Here is what you need to know about Entando 7! We have some exciting updates, features, and fixes. Keep reading to learn more about it!
-tags:
-- Application Composition
-- Modernization
-- Entando 7.0
-title: What’s new with the Entando 7.0 Release?
----
-
-Entando is all set with its new release! Would you like to learn more about it? If yes, then this blog will give you a perfect sneak peak of everything we released with version 7.0.
-
-Entando 7 lets us build a composable business model using composable applications. Composable business allows enterprises to rapidly adapt to market shifts and opportunities by allowing rapid recomposition of services and products. Composable applications enable composable business by allowing the applications and infrastructure required to support the business to change quickly, at low cost, and at greatly reduced risk.
-
-Apart from this, the new Entando Hub supports code reuse for major enterprises and System Integrator (SI) partners. It also aligns pro-code development with low-code composition. The question here is, do you really know what the Entando Hub is?
-
-The Entando Hub enables a team to share components across Entando Applications. The hub allows users to:
-
-- Centralize components and business capabilities for use across teams, groups, or clients
-
-- Publish, manage and communicate component features, versions and metadata
-
-- Perform business-level assessment of component readiness
-
-
-
-The new Entando Hub provides a repository for application modules. Modules can be individual application components, collections of components called packaged business capabilities (PBCs), or complete solutions or solution templates. The hub provides a simple interface, or marketplace, to store modules and make them discoverable across multiple development teams and applications. The hub works in conjunction with Git allowing development teams to work in the same way they do today, but with a web interface to simplify the interaction between creators of pro-code modules and application composers assembling applications from the hub. The hub also provides module curators with a location to enforce IT governance. The hub is available to developers, enterprises, and solution providers as a SaaS, or for private installation on-prem or in the cloud.
-
-Our Partner Program is helping SIs attract new customers and revenue streams for customers adopting composable applications on Kubernetes. If you are interested in learning more about our Partner Program, drop us a line at <partner@entando.com>.
-
-Now, let's also take a look at the Entando Component Generator (ECG). The ECG is a JHipster blueprint that generates Entando-compatible Java applications and micro frontends. With the release of Entando 7, the ECG has now been upgraded to use JHipster 7.2!
-
-The Entando CLI has also been improved. The ent CLI provides a set of commands that accelerate the developer experience by assisting with common tasks such as quickly installing a new copy of Entando, generating an Entando project via JHipster, deploying an Entando Bundle, etc. To learn more about the fixes and changes, take a look at our release notes.
-
-Many interesting features, right? Well, if you're new here, why don't you get started? You can get started through our documentation.
-
-While we are doing all these amazing things, we are also building a community that focuses in-depth on composability and modularity. The goal of this community is to grow an awareness and culture about composable applications. And none of this would be possible without your support, love and contribution. If you are really interested in learning more and getting started with us, join our discord server and say hi!
-
-Let us know your feedback on Entando 7.0!
-
-Thank you!
-
- Back to top
\ No newline at end of file
diff --git a/vuepress/docs/_posts/2022-05-03-using-react-to-create-mfe.md b/vuepress/docs/_posts/2022-05-03-using-react-to-create-mfe.md
deleted file mode 100644
index a27bb29f68..0000000000
--- a/vuepress/docs/_posts/2022-05-03-using-react-to-create-mfe.md
+++ /dev/null
@@ -1,239 +0,0 @@
----
-author: Anthony Viard
-date: 2022-05-03
-summary: Having discovered micro frontend creation with Angular, we jump into another world with React. Remember, I'm trying to create a micro frontend using the web component specifications for Angular, React, and Vue.js. Does React provide the best developer experience when creating a micro frontend social card? Let's try it!
-tags:
-- Developer Topics
-- Open Source
-title: Using React to Create a Micro Frontend
----
-
-
Disclaimer: This article has been written with the help of the ModSquad Community. The related live session is available here:
-
-
-
-
-## Introduction
-
-
Hi, fellow developers!
-
-
Having discovered micro frontend creation with Angular, we jump into another world with React. Remember, I'm trying to create a micro frontend using the web component specifications for each of the following frameworks: Angular, React, and Vue.js.
-
-
Does React provide the best developer experience when creating a micro frontend social card? Let's try it!
As seen in the previous blog, you need to have npm installed. You can then run npx create-react-app react-social-card to create the application skeleton.
-
-
Once complete, you should have a new React project available in the react-social-card folder.
Before configuring the custom-element, we have to create the React social card component. After some research, here is an example of code we can use: https://codepen.io/leoraw/pen/ZjvRpL. Thanks to @leoraw for sharing this example.
-
-## Create the React components
-
-
The social card is split into two different React components: a button box and the card itself.
-
-
First, we create a new file for the button box in the components folder, name it ButtonBox.js and copy this code:
Then, in the same folder, we create the SocialCard.js file and copy the following content.
-
-
Please note, this new component imports and uses the previous one. Effectively, the internal architecture in the micro frontend allows us to use multiple components, and all the components are built into one custom element.
-
-``` js
-import React from "react";
-import ButtonBox from "./ButtonBox";
-
-const UiCard = props => {
- let {image, title, content} = props.content;
- return (
-
-
- );
- }
-}
-
-export default SocialCard;
-```
-
-## Use the new components in the main App.js file
-
-
Once these two components are available, we can update the main App.js file and remove the old React demo code.
-
-
Update the App.js file by replacing the existing code with this:
-
-``` js
-import React from 'react';
-import './App.css';
-import SocialCard from "./components/SocialCard";
-
-const cardDetails = {
- id: 0,
- content: {
- title: 'Shiba Inu',
- image: 'https://material.angular.io/assets/img/examples/shiba2.jpg',
- content: 'The Shiba Inu is the smallest of the six original and distinct spitz breeds of dog from Japan. A small, agile dog that copes very well with mountainous terrain, the Shiba Inu was originally bred for hunting.',
- },
- likeIsClicked: true,
- likes: 5
-}
-
-function App() {
- return (
-
- );
-}
-
-export default App;
-```
-
-
You can see that we are instantiating a new social card component and giving it some data to display.
-
-
Now you can restart the application or refresh the page to see our social card appear. However, this is still a raw React application and we need to define the custom-element to finish our task.
-
-
-
-## Switch the app to a custom element
-
-
In the src folder, at the same level as the components folder, we create a new folder named custom-element.
-
-
Next, let's create a new file named social-card-app.js to define the custom-element using the related API:
The string "react-social-card" is used to define the custom-element tag and renders the React app using <App/>. It's analogous to Russian dolls: custom-element > React app > social card component > buttonbox component.
-
-
Then, in the following public/index.html file, replace the body with this:
-
-``` html
-
-
-
-
-```
-
-
Reload your browser and check the HTML content:
-
-
-
-
The react-social-card custom element is used and loads the React app content.
-
-
Congratulations! You've just created your first micro frontend using React!
-
-## Resources
-
-- The code above is available on GitHub here.
-
-- Watch micro frontend videos on our YouTube channel.
-
-- Join us on Discord to share and learn about composable apps.
-
- Back to top
-
diff --git a/vuepress/docs/_posts/2022-06-15-using-vue-to-create-mfe.md b/vuepress/docs/_posts/2022-06-15-using-vue-to-create-mfe.md
deleted file mode 100644
index 92943375d4..0000000000
--- a/vuepress/docs/_posts/2022-06-15-using-vue-to-create-mfe.md
+++ /dev/null
@@ -1,235 +0,0 @@
----
-author: Anthony Viard
-date: 2022-06-15
-summary: After learning how to create micro frontends with Angular and React, we’re jumping into another world with Vue.js. Remember, we’re trying to create a micro frontend using the web component specifications for Angular, React, and Vue.js. Does Vue provide the best developer experience when creating a micro frontend social card? Let’s try it!
-tags:
-- Developer Topics
-title: Using Vue.js to Create a Micro Frontend
----
-
-
-
-Disclaimer: This article has been written with the help of the ModSquad Community. The related live session is available here:
-
-
-
-
-
-## Introduction
-
-
-Hi, fellow developers!
-
-
-After learning how to create micro frontends with Angular and React, we’re jumping into another world with Vue.js. Remember, we’re trying to create a micro frontend using the web component specifications for each of the following frameworks: Angular, React, and Vue.js.
-
-
-Does Vue provide the best developer experience when creating a micro frontend social card? Let’s try it!
-
-
-## Create the Vue.js app
-
-
-First, ensure that you have installed Node with npm (you can use Yarn instead) and Vue CLI: npm install -g @vue/cli
-
-
-
-
-I suggest using the default option Default ([Vue 3] babel, eslint) to create the application by running the following command in your target folder: vue create vue-social-card
-
-
-
-That should create a folder named vue-social-card that contains a fresh Vue.js project.
-
-
-
-
-
-Please note that by default, the application is configured to include certain features, such as npm scripts to start your app and eslint to help you code.
-
-
-## Discover your application
-
-
-Before making any changes and creating a micro frontend, let’s run the application locally using npm run serve. Your application should then be available at the following URL: http://localhost:8080/.
-
-
-
-
-## Create the social card component
-
-
-Vue.js helps you organize your code with components. That means we need to create a file to contain all the card code. You can delete the default file called HelloWorld.vue.
-
-
-Once you’ve created a new file named SocialCard.vue in the components folder, copy the following code into it:
-
-
-``` js
-
-
-
-
-
{{ card.name }}
- {{ card.description }}
-
-
-
-
-
-```
-
-
-Our component is just a simple piece of HTML/CSS code that requires an entry object named card and defines the following properties: name, description, image, and image_alt.
-
-
-As it is, your application might be broken due to an error in the app.vue file. It’s time to update it.
-
-
-## Update App.vue
-
-
-The reason your app doesn’t work is that the main component still includes the default component. To fix it, replace the file contents with the following code:
-
-
-``` js
-
-
-
-
-
-```
-
-
-This imports our social card component, defines a card object shiba_card in the data() function to store the different properties, then passes the card object to the social card component in the template section.
-
-
-The application is working again and the default Vue landing page is replaced with the Shiba Inu social card:
-
-
-
-
-
-However, we only built a classic single page application and need to migrate it to a micro frontend.
-
-
-## Define the custom element
-
-
-
-In order to reuse this app as a web component, we need to define a custom element, which is a typical step when using Angular and React.
-
-
-Replace the contents of the main.js file with the following:
-
-This code defines the social-card-element custom element and wraps the Vue app. As we saw before, this app is now rendering the card as expected.
-
-
-Next, replace <div id="app"></div> in the public/index.html file with the custom element:
-
-
-``` js
-
-
-
-
-
-```
-
-
-Congratulations! You have just built a Vue.js micro frontend using a custom element.
-
-
-Please note, as I’m writing this article, there is an issue with styling and custom elements that is discussed in detail here. Please follow this ticket to know when it will be fixed or for current workarounds.
-
-
-## Resources
-
-- The code above is available on GitHub here.
-
-- Thanks to this repo for the card example.
-
-- Are you already using Entando and looking for Vue.js components? Take a look at this sample.
-
-- Watch micro frontend videos on our YouTube channel.
-
-- Join us on Discord to share and learn about composable apps.
-
- Back to top
-
-
-
diff --git a/vuepress/docs/_posts/2022-06-15-what-is-the-hub.md b/vuepress/docs/_posts/2022-06-15-what-is-the-hub.md
deleted file mode 100644
index 8e6a0152d4..0000000000
--- a/vuepress/docs/_posts/2022-06-15-what-is-the-hub.md
+++ /dev/null
@@ -1,89 +0,0 @@
----
-author: Sohini Pattanayak
-date: 2022-06-15
-summary: This is a mini-tutorial to help you understand what the Entando Hub is. It is a repository (local, remote, public, or private) that contains components. Not only that, it has several capabilities and features. To explore all of that, this blog is definitely a must-read!
-tags:
-- Blog
-- Product / Support
-- Components / Hub
-title: What is the Entando Hub?
----
-
-
What do you imagine when someone says hub?
-
-
It's a center or place to hold a collection of things or several kinds of things. An Entando Hub is a repository (local, remote, public, or private) that contains components. To be more specific, the App Builder, which is the UI of the Entando Platform, can connect to one or more Entando Hubs.
-
-
In my recent blog on the Entando 7.0 release, I wrote a bit about the Entando Hub. You can check that out here. But, in this blog, I'll give a technical overview of the hub.
-
-
Before I start, let's find out why we needed a hub.
-
-
In previous blogs, we learned about the 4Cs. If you don't know about that, you can take a look at this blog. From the 4 essential roles of application composition, one thing is clear: the set of components built by Creators are reusable and flexible. But, to make them easy to reuse, there was a need to create a hub, where they could reside and be available to a larger audience.
-
-
Now, the question is, what are some of the capabilities of the hub?
-
-
The hub lets you share single components, component collections, solution templates, and packaged business capabilities (PBCs) that Creators build.
-
-
-
-
A single components is a building block for apps. It can be a page template, content template, micro frontend, microservice, UX Fragment, or content type.…
-
-
-
-
Component collections are a packaged set of single components. They are assembled components that are in some way functionally unrelated but useful to a Composer (e.g. a set of Page Templates, a set of content templates or content types plus widgets and MFE, or a mix of these).
-
-
-
-
Solution templates are a pre-packaged set of PBCs, component collections, and single components providing full-featured, domain-specific solutions (e.g. Task Tracker, Supplier Portal, Customer Portal, Partner Portal, E-commerce, etc.).
-
-
-
-
PBCs are encapsulated software components that represent a well-defined business capability, recognizable as such by a business user, and packaged for programmatic access.
-
-
-
-
Any and all of these can be assembled in the hub, where new items and new versions are continuously made available. But to avoid errors or issues, we should follow some best practices:
-
-
-
The PBCs and/or components Creators build must be appropriately sized - not too small or too big. They should be business-driven with a definite business value. There are several scenarios for this. For example, a PBC can have many components which make it large, or it can have fewer components, making the size smaller. But in the latter case, a Composer may need to install several of these smaller PBCs. It is a tradeoff between functionality and ease of use. Hence, we must judge wisely, making sure the component isn't too large or too small.
-
-
Our components and PBCs should be easily configurable. By this, I mean we must avoid hardcoding. It is preferable to use separate configuration files or database tables to store any value that's needed in your component.
-
-
It is best to use a package manager to help with the right dependency versioning strategy. A package manager helps us by updating all the packages and/or software frequently. These packages run tests to check security, etc., and save us a lot of time.
-
-
While we discuss these best practices, we must know that the Curator oversees the hub, managing the components available there for the organization. Hence, the Curator should do a Security Analysis. They should perform a thorough analysis of the dependencies, security alerts and/or code vulnerabilities.
-
-
Use code quality metrics to measure and determine if the code we have written for the PBC is of high quality. Certain variables are checked under this quality analysis, like code complexity, portability, reusability, etc.
-
-
And finally, we should add proper documentation for our PBC. It's the first thing that provides clarity about our PBC. This documentation should be created in such a manner that it is well understood by both business and technical people. Also, it is a good coding practice!
-
-
-
Now, it's time we take a look at the Entando Hub.
-
-
-
-
As you see here, there are many single components, component collections, solution templates, and PBCs under “Catalog”. After the Curator performs the validation checks, these building blocks made by Creators are published in the hub.
-
-
How can we use the hub?
-
-
This hub can be used with Entando 7.0. This documentation can help us get started, but in the upcoming blogs, I'll definitely share how it can be installed in our App Builder.
-
-
Is the hub open source?
-
-
The Entando Hub is under the LGPL-3.0 license and is open source. We can easily contribute to it by referring to this repository.
-
-
Lastly, before we wrap up, I'd like to explain the Entando Cloud Hub.
-
-
The Entando Cloud Hub is a SaaS instance of an Entando Hub that contains a public and private collection of components.
-
-
Well, that's all about the hub for now. We are in the process of creating more tutorials around the hub and those will be released over the next few weeks.
-
-
But, for now, I would love to see you all try out the hub for yourselves and send in your feedback using the comment section below!
-
-
-
-
Lastly, we at Entando are building an exciting community that spreads awareness of composability and modular applications. We call it the Modular Squad, and we'd love to invite you to join us and be part of this journey!
-
-
Thank you!
-
- Back to top
-
diff --git a/vuepress/docs/_posts/2022-07-12-update-on-k8s-support.md b/vuepress/docs/_posts/2022-07-12-update-on-k8s-support.md
deleted file mode 100644
index 6273b13aaf..0000000000
--- a/vuepress/docs/_posts/2022-07-12-update-on-k8s-support.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-author: Entando
-date: 2022-07-12
-summary: Entando's policy is to support three active releases of Kubernetes. Support for each K8s release ends no sooner than three months after the official Kubernetes End of Life date to give our customers and partners time to upgrade their Kubernetes version. The following is the current Entando timeline.
-tags:
-- Entando 6.3.2
-- Entando 7.0
-- Product / Support
-title: Update (July 2022) - Kubernetes support for Entando 6.3.2 and 7.0
-cover: images/covers/entando-logo.png
----
-
-
Entando's policy is to support three active releases of Kubernetes. Support for each K8s release ends no sooner than three months after the official Kubernetes End of Life date to give our customers and partners time to upgrade their Kubernetes version. You can find the Kubernetes release timeline here: https://kubernetes.io/releases/.
-
-
The following is the current Entando timeline:
-
-
-
May 2022 - Entando 7.0 and 6.3.2 - support was added for K8s 1.22 via fixpacks 6.5.1 and 7.0.2, respectively
-
August 2022 - Entando 7.0 and 6.3.2 - support will be added for K8s 1.23
-
October 2022 - Entando 7.0 and 6.3.2 - support will be added for K8s 1.24
-
- Back to top
\ No newline at end of file
diff --git a/vuepress/docs/_posts/2022-08-11-entando7-release-overview.md b/vuepress/docs/_posts/2022-08-11-entando7-release-overview.md
deleted file mode 100644
index 0109ebc75b..0000000000
--- a/vuepress/docs/_posts/2022-08-11-entando7-release-overview.md
+++ /dev/null
@@ -1,102 +0,0 @@
----
-author: Sohini Pattanayak
-date: 2022-08-11
-summary: The 7.1 release is finally out! And here's what you need to know about the new features and updates!
-tags:
-- Product / Support
-- Entando 7.1
-title: Entando 7.1 Release Overview
----
-
-Entando's Application Composition Platform Version 7.1 is now available to support enterprises that are modernizing applications to accelerate development, reduce runtime costs, and streamline maintenance through the use of a composable application architecture. Entando brings developer joy to the creation, curation, and composition of modular enterprise applications.
-
-
-
-Background:
-
-Even before the 21st century, enterprises have been advancing infrastructure and strategies to solve business problems. From the development of web applications on-prem to their subsequent move to the cloud, and now, modularization in the cloud, each move has accelerated development, lowered cost and streamlined maintenance.
-
-This new phase of modularity focuses on decoupling (or breaking up) both the backend code and the monolithic frontend by bundling microservices and micro frontends into packaged business capabilities (PBCs). These PBCs can be shared across development teams and projects within an Enterprise Hub and assembled into applications via a low-code Application Builder, all within a unified Application Composition Platform.
-
-The updates available in Entando 7.1 are focused on the pro-code creators. It provides many new capabilities to support the development of modern composable applications, which include:
-
-New: Entando Platform Capability (EPC)
-
-To accelerate application development, Entando 7.1 now supports a pluggable framework to allow Creators and Composers to easily expand the functionality of the Entando App Builder and add external services. Like the PBC, an EPC is a packaged capability, and it adds functionality to the platform like menu options or an API management page. An EPC can be a headless CMS, like Strapi, that is bundled, stored in the Entando Cloud Hub, and implemented in the App Builder.
-
-A sample configuration is shown below:
-
-
-
-
The headless system (e.g. Strapi) uses the Entando App Builder as a templating mechanism to create and manage pages, content layout, and content versioning:
-
-
1) An EPC can be deployed to an Entando Hub (such as the Entando Cloud Hub, the publically accessible version of the hub).
-
-
2) EPCs can be installed into and then accessed from the Entando App Builder. This adds a new menu item to the App Builder.
-
-
3) When the menu item is accessed, it opens the headless interface, where content can be managed. You can return to the App Builder at any time.
-
-
4) Users can access the external system's APIs and resources, deploying them into applications using the page designer. Many types of EPCs can be built for Entando 7.1, including a headless CMS (Strapi.io is coming soon), Workflow, AI/ML, API Mgmt, and more.
-
-
New: Bundle Templates
-
-
Entando 7.1 introduces pro-code bundle templates to enable developers, System Integrators, and enterprises to create new PBCs by reusing existing micro frontends and microservices, providing consistency and acceleration from a core PBC library.
-
-
-
-
New: Service Discovery
-
-
With Entando 7.1, communication between micro frontends and microservices is decoupled. Service discovery is simplified with the API claims mechanism orchestrated by the ent CLI, which eliminates the need to define and manage API endpoints, both in local development and within a running instance.
-
-
Updated: Create Tooling
-
-
Entando 7.1 mainly focuses on developers. The local development process was improved and now developers can easily initialize a bundle from scratch or download one from a hub. They can add components and populate the bundle descriptor with micro frontends, microservices, and platform components with the ent CLI. They can run, build, and install with only a few commands. Bundles that have worked on 7.0 will work on 7.1 as well. More details can be found here: https://developer.entando.com/v7.1/docs/getting-started/ent-bundle.html
-
-
Updated: Docker Image Specification
-
-
Previously, developers used Git repositories to manage both code sources and bundle versioning. Now bundle packaging and publishing uses Docker to handle the image specifications. With this, one can still manage code sources on their preferred Git provider, but each release will be done through an image registry.
-
-
Updated: Entando CLI
-
-
We have enhanced the Entando CLI for Mac and Windows. The CLI can now create new bundles from templates downloaded from an Entando Hub, which provide a wider range of commands to perform various actions. Some examples:
-
-
-
Create a Docker image of the bundle
-
Docker-based bundle management commands
-
Easily publish a bundle inside Docker Hub
-
API management
-
-
-
Updated: Entando Hub
-
-The Entando Hub was introduced in Entando 7.0 and provides a repository for PBCs, solution templates, components, and/or component collections. Enterprises, development teams, System Integrators, etc., can implement an Entando Hub as a central repository from which the Entando App Builder can discover and quickly access entries. Entando Hub updates include:
-
-
-
Docker bundle name generation update
-
Added bundle security check
-
Update install instructions to use `ent ecr deploy`
-
Refined bundle retrieval to sort entries in the App Builder
-
-
-
Summary
-
-
To learn more about Entando 7.1, or to get started with composable applications, see:
-
- Back to top
\ No newline at end of file
diff --git a/vuepress/docs/_posts/2022-09-19-update-on-k8s-support.md b/vuepress/docs/_posts/2022-09-19-update-on-k8s-support.md
deleted file mode 100644
index fc1dbd2d22..0000000000
--- a/vuepress/docs/_posts/2022-09-19-update-on-k8s-support.md
+++ /dev/null
@@ -1,24 +0,0 @@
----
-author: Entando
-date: 2022-09-19
-summary: Entando's policy is to support three active releases of Kubernetes. Support for each K8s release ends no sooner than three months after the official Kubernetes End of Life date to give our customers and partners time to upgrade their Kubernetes version. The following is the current Entando timeline.
-tags:
-- Entando 6.3.2
-- Entando 7.0
-- Product / Support
-title: Update (Sept 2022) - Kubernetes support for Entando 6.3.2 and 7.0
-cover: images/covers/entando-logo.png
----
-
-
Entando's policy is to support three active releases of Kubernetes. Support for each K8s release ends no sooner than three months after the official Kubernetes End of Life date to give our customers and partners time to upgrade their Kubernetes version. You can find the Kubernetes release timeline here: https://kubernetes.io/releases/.
-
-
The following is the current Entando timeline:
-
-
-
September 2022 - Entando 7.0 and 6.3.2 - support was added for K8s 1.23 via existing fixpacks 7.0.2 and 6.5.1
-
November 2022 - Entando 7.0 and 6.3.2 - support will be added for K8s 1.24
-
- Back to top
diff --git a/vuepress/docs/_posts/2022-12-19-explore-docker-bundles.md b/vuepress/docs/_posts/2022-12-19-explore-docker-bundles.md
deleted file mode 100644
index 8925fac97d..0000000000
--- a/vuepress/docs/_posts/2022-12-19-explore-docker-bundles.md
+++ /dev/null
@@ -1,301 +0,0 @@
----
-author: Anthony Viard
-date: 2022-12-19
-summary: At Entando, we define a bundle as a package that contains one or more components. A bundle can be a single component, component collection, PBC, or solution template, based on the level of granularity. Any bundle built with Entando is an Entando Bundle. Entando 7.1 introduces a major new change - bundles with a docker-based structure. This article explores all the things you need to know about this feature.
-tags:
-- Community
-- Entando 7.1
-title: Explore docker-based bundles with JHipster and Entando 7.1
----
-
-
At Entando, we define a bundle as a package that contains one or more components. A bundle can be a single component, component collection, PBC, or solution template, based on the level of granularity. Any bundle built with Entando is an Entando Bundle.
-
-
Entando 7.1 introduces a major new change - bundles with a docker-based structure. This article explores all the things you need to know about this feature.
-
-## A shift from git-based bundles
-
-
If you've already built or used bundles with Entando, you should know that before Entando 7.1, the bundles were git-based. That means the source code (or project) and the build artifact (the deployable bundle) were stored in two different Git repositories.
-
-
Traditionally, the source code repository is used by the Creators team for coding and building components with development tooling. The coding flow is similar to what we find in any development team, pushing and merging branches to share and review the code within the team.
-
-
The second repository stores the result of the compiling process, the artifact, that Curators can register in a hub, and Composers can install on their Application Composition Platform.
-
-
The docker-based bundle is a total shift from this. The source repository is still present, but all the artifacts are now sent to a Docker registry using Docker images.
-
-## A structure modification
-
-
The publishing process was improved with the tool change, so we took the opportunity to streamline the bundle structure itself.
-
-
We have a more readable and consistent set of folders with the docker-based bundles.
-
-
-
-
-
git-based
-
docker-based
-
-
-
bundle/descriptor.yaml
-
The main bundle descriptor
-
-
entando.json
-
The main Entando file that contains the component definitions and metadata
-
-
-
-
ui/
-
The micro frontends sources folder
-
-
microfrontends/
-
Centralized micro frontends folder
-
-
-
-
src/
-
The backend sources folder
-
-
microservices/
-
The microservices folder, one per component
-
-
-
-
src/main/docker
-
The auxiliary service folder, such as Docker compose files and the Keycloack configuration for local usages
-
-
svc/
-
The auxiliary service folder, such as Docker compose files and the Keycloack configuration for local usage
-
-
-
-
*.sh
-
Shell script used by the CLI to compile and build the bundle
-
-
-
-
-
-
platform/
-
The folder for any Entando-related component such as pages, contents, page templates… One sub-folder per component type
-
-
-
-
-
-
If you'd like to make an in-depth comparison between these implementations, our documentation provides a table here.
-
-
The CLI and commands are now using the docker-based structure, which can be created easily.
-
-
Let's start a new project to discover this.
-
-## Create a new 7.1 bundle with the ent CLI
-
-### Prerequisites
-
-
Before moving forward, you have to ensure that your Entando CLI is up to date. If not, please run the following command:
In the project folder, run the following command to add a new microservice:
-
-``` sh
-ent bundle ms add sample-ms --stack=spring-boot
-```
-
-
We specify the stack because of the dedicated metadata we may need with some stack types. This command creates a new folder called "sample-ms" in the "microservices" folder and adds an entry in the entando.json.
Please note, this new folder is empty and you have to add your own code. We provide an easy way to start; let's do it with JHipster.
-
-
Call JHipster with the following commands:
-
-``` sh
-cd microservices/sample-ms
-```
-``` sh
-ent jhipster --blueprints=entando
-```
-
-
Then, select only the default values.
-
-
When the generation is done, the "sample-ms" folder contains all the files provided by JHipster.
-
-### Customize the bundle for JHipster
-
-
You just need to tweak a couple of things to make it work properly.
-
-First, edit the entando.json and update microservices/sample-ms to set the healthCheckPath and dbms properties:
-
-``` json
-{
- "healthCheckPath": "/management/health",
- "dbms": "postgresql"
-}
-```
-
-Next, move the blueprint-provided auxiliary service definitions into the svc directory in the bundle project:
-
-``` sh
-mv microservices/sample-ms/src/main/docker/* svc/
-```
-
-
For advanced use cases, you can add MFEs with this tutorial. Please note that for microservices, you have to execute some extra steps.
-
-### Discover the new publishing process
-
-
This new bundle structure comes with a simpler publishing process provided by new streamlined CLI commands.
-
-
You can find a graphic of the different steps below. It describes the overall process and helps you to understand the details involved in every step.
-
-
-
-
Let's follow it for our new 7.1 bundle.
-
-#### Build
-
-
From the root project folder, run the following command:
-
-``` sh
-ent bundle pack
-```
-
-
Please note, you need to have Maven installed for this to execute. You also need Docker installed; you can check the installation procedure appropriate to your environment.
-
-
-
-
You can run the "docker image ls" command to see your available images.
-
-
-
-#### Publish
-
-
Once it's finished, run the next command to publish the bundle to a Docker repository:
-
-``` sh
-ent bundle publish
-```
-
-
In this step, you need to be logged into Docker Hub. Ensure you have an account or create a new one on this website: https://hub.docker.com
-
-
Please note, you can decide to publish the images to another registry by providing the URL with the --registry parameter.
-
-
-
-
-
-#### Deploy
-
-
This step is the same as for the previous Entando version, even if the commands have been modified to keep the consistency. Here, you need to have an available running instance of Entando. Visit https://developer.entando.com to install a local one.
-
-
Please note that you need your ent CLI profile to be connected to your Entando instance. If you followed the previous steps and installed a local multipass VM, you might have to run the following command, where “entando” is the virtual machine name:
-
-``` sh
-ent attach-vm entando
-```
-
-
Otherwise, it is possible to attach a kubeconfig file with this:
-
-``` sh
-ent attach-kubeconfig {kubeconfig-file}
-```
-
-
From your bundle root folder, run the following command:
-
-
-
-
When the deploying process is finished, you can navigate to your Local Hub by clicking on the “Hub” menu.
-
-
-
-
Then, you should see your bundle:
-
-
-
-#### Install
-
-
As you can see, the bundle is available in your Local Hub but not installed yet. That means nothing is running on your cluster from that bundle and the components are not available for composition.
-
-
To install them, you can use the UI and click on the "Install" button in the Local Hub, or you can run the following command from your bundle root folder:
-
-``` sh
-ent bundle install
-```
-
-
-
-
The micro frontends are now available in the App Builder to compose new pages. The microservices are pods and you can check them with the following:
-
-``` sh
-ent kubectl get pods -n entando
-```
-
-## Conclusion
-
-
In this article, we discovered a few new features provided by Entando 7.1. The bundle structure has been rebuilt and they are now docker-based. The publishing process has been optimized with the ent CLI commands. The JHipster blueprint has been optimized to match this new paradigm.
Did you know the bundle we just created can be used like a template to create a new one? Maybe not, because that's also a new feature in 7.1 and this is the topic of the next blog post in this series. Stay tuned.
-
- Back to top
\ No newline at end of file
diff --git a/vuepress/docs/_posts/2023-01-26-composable-apps-security-k8s.md b/vuepress/docs/_posts/2023-01-26-composable-apps-security-k8s.md
deleted file mode 100644
index 2fbb934e54..0000000000
--- a/vuepress/docs/_posts/2023-01-26-composable-apps-security-k8s.md
+++ /dev/null
@@ -1,34 +0,0 @@
----
-author: Anthony Viard
-date: 2023-01-26
-summary: Building composable apps means understanding how they manage security and reliability. Composable apps offer a lot of advantages to streamline applications due to the modularity and reusability of packaged business capabilities.
-tags:
-- Application Composition
-title: Composable Apps Security Practices with Entando on Kubernetes
----
-
-Building composable apps means understanding how they manage security and reliability. Composable apps offer a lot of advantages to streamline applications due to the modularity and reusability of packaged business capabilities (PBCs). Individual modules and PBCs help isolate problems and security designs, separate frontend and backend concerns, and allow patching at the component level. At the company level, and with a good hub policy, this turns into “patch once, secure all” because you can easily leverage security fixes if they are applied to centralized modules in a store that all your applications rely on.
-
-![Entando Platform Development Process](./images/2023-01-26-process.png)
-
-However, security strategies should not be applied at the code or module level only. The infrastructure has to be fully resilient and secure. No one can imagine using a car with seatbelts within an insecure chassis. It doesn't make sense. Security is everyone’s business.
-
-Fortunately, solutions exist to help us design at all levels with security as one of the top priorities.
-
-"Shift security left." It is more than a buzz phrase, it's good advice according to Lucas Ward in a recent article called [Hardening Kubernetes and What That Entails With Entando](https://blog.ippon.tech/hardening-kubernetes-and-what-that-entails-with-entando/). There, Ward describes how building applications with Kubernetes is challenging.
-
-I agree, building a fully secured application with Kubernetes is a real adventure. If there is something we can't live without, it is security. Whatever business domain we work in, security should be at the center of the design and production processes.
-
-Delaying its implementation is risky; executing it is time consuming.
-
-As Ward spells out, we can rely on frameworks for a smooth and dependable way to secure applications, especially with Kubernetes. He says that using a platform such as Entando provides simplicity and a solid foundation with best practices you can count on to promote security from the ground up.
-
-
-
-
-
-From solid structures and basic setup with code generation, to a well documented CI/CD process and opinionated build pipelines, Ward asserts that "using Entando as your platform of choice covers a lot of ground in the Development, Build, and Infrastructure scape."
-
-Saying more without spoiling it is impossible - just read it! This is my only advice.
-
- Back to top
\ No newline at end of file
diff --git a/vuepress/docs/_posts/2023-03-17-building-business-based-autonomous-components.md b/vuepress/docs/_posts/2023-03-17-building-business-based-autonomous-components.md
deleted file mode 100644
index 3f5cceb016..0000000000
--- a/vuepress/docs/_posts/2023-03-17-building-business-based-autonomous-components.md
+++ /dev/null
@@ -1,192 +0,0 @@
----
-author: Colin Damon
-date: 2023-04-03
-title: "Domain-Driven Architectures: Building business-based autonomous components"
-summary: In today's digital age, organizations seek innovative solutions to keep up with the ever-evolving needs of their customers. One of the most promising approaches is to create highly modular, scalable, and adaptable applications.
-tags:
-- Hexagonal Architecture
-- Business-Driven Development
-- Architecture
-- Composable Applications
-cover: images/covers/2023-03-17-cover.png
----
-In today's digital age, organizations seek innovative solutions to keep up with the ever-evolving needs of their customers. One of the most promising approaches is to create highly modular, scalable, and adaptable applications.
-
-
-
-Composable apps and Hexagonal Architecture go hand-in-hand in achieving that goal. The goal of composable apps is to build applications as a set of loosely-coupled, independently deployable components that are combined to meet the needs of users. Hexagonal Architecture provides a framework for achieving this goal by organizing the application around its core business logic and making it agnostic to the surrounding technical infrastructure.
-
-It would be a mistake to think a developer would naturally use one or both. First, because composable apps are quite new in IT, and then because even though Hexagonal Architecture is getting more popular, there are many things to know to be domain-centric.
-
-Combining both is a great choice and here we explain why.
-
-In this blog, we will delve into the concepts of composable apps and domain-driven architecture, with a specific focus on Hexagonal Architecture. By the end of this blog, you will have a deep understanding of how Hexagonal Architecture can be leveraged to build applications that deliver fast business value for the users.
-
-
-# Split by Business domain, not by tech domain
-
-Splitting applications into autonomous parts is really challenging! Unfortunately, it is a mandatory step if your solution is meant to grow.
-
-Most of the time, following [Conway’s Law](https://en.wikipedia.org/wiki/Conway%27s_law), applications are split around technical responsibilities. This way, it will be easier to build dedicated, specialized teams for each “component."
-
-This approach is not really efficient since you’ll have to synchronize the development and delivery cycle for each component (this is probably not what you are looking for when splitting things).
-
-Another approach is to split autonomous components around business capabilities; let’s dig into that.
-
-
-# Modeling the Domain
-
-First things first: we have to support enforcing the business with our application. This means we’ll need to write code really expressing our domain.
-
-This code can be object-oriented or functional (either works) but must:
-
-
-
-* Have no dependency on any framework
-* Have no hidden side effects
-* Be really expressive
-
-We are so used to writing code around technologies that writing this code with these requirements is the really challenging part. You don’t need to think about the persistence or the message queue at this step, you “only” need to code an answer to business problems.
-
-To do that, you can start with type-driven development (yep, that’s another TDD…). The goal is to start expressing your domain by creating types that will disallow any state that's not supposed to exist. If it is impossible to do impossible actions, everything will be easier.
-
-A short example of that: you are building a survey application where you want to send emails with unique links to users. The users can then click the link and answer their survey. If you have only one `Questionnaire` class, you’ll have to have an `answer(...)` method on it to get user answers. Problem is, what happens when you answer an already answered questionnaire? Another solution is to have a `QuestionnaireToAnswer` with an `answer(...)` method resulting in an `AnsweredQuestionnaire`. That way, at every step, you can ensure that your questionnaires are in valid states with dedicated and coherent methods.
-
-Another great approach to focusing on the domain problems: test-driven development. This TDD is really easy to misunderstand! It’s not a testing methodology, it’s a very powerful design approach. It is meant to get to better design faster, but it takes a lot of practice to get to that point.
-
-> To get a better understanding of the misunderstandings around TDD you can watch [TDD, Where Did It All Go Wrong (Ian Cooper)](https://www.youtube.com/watch?v=EZ05e7EMOLM)
-
-Let’s go back to our previous survey example. It is really easy to write tests on the `answer(...)` method and check the resulting `AnsweredQuestionnaire`. If I want to build complicated indicators, I will really appreciate the fact that I can write blazing fast tests (talking in ms here). This really quick feedback loop will help me code a working solution and, after that, an elegant and future-proof one.
-
-> Again, learning TDD is really hard and needs practice. A shortcut is to participate in Coding Dojo, organized by the Software Crafters community.
-
-Finally, I can’t talk about a domain model without talking about domain-driven design - the approach that starts expressing that. Domain-driven design is an awesome toolbox to build domain-centric solutions.
-
-If TDD is easy to learn and hard to master DDD is… hard to learn and really hard to master. But it is really worth it! Among many other things, it is giving us the key to split applications into autonomous blocks called bounded contexts (but we’ll come back to that later).
-
-So, we talked about TypeDD, TestDD and DDD but we are still missing the most important thing to build business-oriented solutions: building them with domain experts. Domain experts here are people who really know the domain.
-
-For my survey application, if Bob was there, sending surveys for the past 15 years, I really want to work with Bob on the new solution. Of course, he won’t be able to think of a great solution on its own, but neither will I. We need to work together to find the most suitable solution for everybody.
-
-However, having business-facing code in a vacuum doesn't serve any purpose! We have to, somehow, make that code available to users and systems. We also need interactions with infrastructure elements (databases, queues…). Protecting the domain model while allowing those interactions is the main purpose of domain-centric code architecture.
-
-
-# Domain Model Architectures
-
-There are many domain-centric software architectures. If they all focus on domain model protection, depending on your needs, one may be more suitable than the other.
-
-I’m mainly a Java developer. On the backend, my “default” domain-centric architecture is a peculiar flavor of [Ports and Adapters](https://alistair.cockburn.us/hexagonal-architecture/) (aka Hexagonal Architecture).
-
-With this flavor, of course I’ll start with the domain model at the center:
-
-
-![drawing](./images/2023-03-17-image1.png)
-
-Most of the time, my goal will be to expose domain operations through web services. This is the job of the primary adapter:
-
-
-
-![drawing](./images/2023-03-17-image2.png)
-
-This is where the flavor specificity kicks in: the application layer. This is a very thin layer mainly composed of application services that do:
-
-
-
-* Wiring transactions management
-* Wiring authorization control
-* Really simple orchestration
-
-This layer has framework dependencies so it will be really easy to add the wiring capabilities.
-
-Since the application layer needs to interact with infrastructure we’ll need to add ports and adapters:
-
-
-
-![drawing](./images/2023-03-17-image3.png)
-
-The ports are interfaces in the domain and the secondary adapters are implementations of these ports.
-
-> Ports are in the domain because it is really common to inject them, ex: in domain services.
-
-I really like this architecture because each part is only doing one thing so we can focus on doing it well:
-
-* Primary adapters only need to make an efficient adaptation. For example, they can have great REST documentation without polluting anything else.
-
-* The application is really thin, no real business value here
-
-* The domain code is what really matters so we can focus on its accuracy and expression
-
-* Secondary adapters only need to handle the infrastructure elements' adaptation. For example, we can focus on having a really performant data model for our business cases here.
-
-> This very quick introduction is probably not enough to be able to code in this kind of architecture. You can have a look at [this live coding](https://www.youtube.com/watch?v=mEECPRZjajI) to see it in action.
-
-
-
-If you are using OOP you should give it a try. If this doesn’t suit your needs, you might want to have a look at [Onion Architecture](https://jeffreypalermo.com/2008/07/the-onion-architecture-part-1/) or [Functional Core Imperative Shell](https://kennethlange.com/functional-core-imperative-shell/) if your domain model is in FP.
-
-But, to be honest, this doesn’t really matter. Having a rich domain model (as opposed to an [anemic one](https://martinfowler.com/bliki/AnemicDomainModel.html)) is the important part! You can then protect this domain with the architecture you like as long as it:
-
-
-
-* Exposes operations on your domain model without polluting it
-* Allows interaction with infrastructure without impacting your domain model
-
-In an application, you can have different architecture from one bounded context to the other. Ah, yes, there won’t be one domain model, there will be many of them, one for each bounded context!
-
-
-# Bounded Context?
-
-A bounded context is an autonomous piece of code responsible for one part of the domain logic. Autonomous doesn't mean they can’t communicate with each other!
-
-> If you want to dig into the communication between bounded contexts you are probably looking for [Context Mapping](https://github.com/ddd-crew/context-mapping) but it is not part of this article.
-
-So, bounded contexts are bounded… That means they can have different life cycles and be managed by different teams as long as your Team Topology sticks to code organization.
-
-> If you want to check out how to organize teams around these Bounded Contexts, you might want to apply an inverse [Conway](https://en.wikipedia.org/wiki/Conway%27s_law) maneuver. [Team Topologies](https://teamtopologies.com/) will help in that regard but, again, not part of this article.
-
-Bounded contexts are the parts we are looking for when trying to split a solution. Problem is, they are not really easy to find…
-
-The first element to look at when trying to find bounded contexts is language. If you are using totally different words or the same word with a different meaning that probably means you are in different bounded contexts.
-
-Back to our survey application. To send surveys we have templates with questions. The template notion also exists when sending emails to users. Same word, totally different meanings! This was an easy one. A trickier one is templates in the template context and templates in the questionnaire context. In the template context they are models that can be used to create a new campaign. In the questionnaire context they are the customized models just existing in a campaign. Same word, same idea, totally different usages and users.
-
-There are a lot of hints, apart from language, to find bounded contexts, but I think that the best call is to not try too hard at first. For me, the best way to find bounded contexts is to let them appear in the code as we get deeper insights into the problem we are trying to solve.
-
-This approach is called [MonolithFirst](https://martinfowler.com/bliki/MonolithFirst.html) and the plan is to start with all the code in the same place and extract some parts, little by little. When boundaries are not moving that much we can start splitting the monolith (if needed).
-
-But, this can only work if our code is open to changes, and this is probably the key to splitting applications!
-
-
-# PBCs and Composable Apps are Domain-Centric Approaches
-*A few words from Anthony Viard*
-
-Packaged business capabilities (PBCs) and composable apps align well with domain-centric architecture as they allow businesses to assemble and integrate components that are specifically designed to meet their unique needs.
-
-We can say PBCs have been inspired by Hexagonal Architecture as it provides a structure for organizing business capabilities into modular and scalable components. The idea behind PBCs is to package business functionality into reusable and independent units that can be combined in various ways to meet the needs of different customers.
-
-This is similar to the concept of "ports" in Hexagonal Architecture, where the business logic is isolated and treated as a central component that can be connected to different interfaces (such as user interfaces, databases, or other services) without affecting its core functionality.
-
-By leveraging the principles of Hexagonal Architecture, PBCs can be developed in a way that is decoupled from the underlying technology, making it easier to make changes to the technology stack without affecting the business capabilities. By following this architectural pattern, PBCs can be designed and developed in a way that is flexible, scalable, and easy to understand, making them a powerful tool for delivering business value.
-
-Understanding bounded contexts helps you design the PBCs you need to use or to develop. It is funny to see that both Hexagonal Architecture and PBCs are symbolized by a hexagonal shape, as they are both centered around the core business logic, but they are conceptually applied at different levels.
-
-On the other hand, PBC structure benefits from composable apps, which are used as bricks of business logic - independently composable, using interfaces to communicate, and offering business-oriented contracts.
-
-Hexagonal Architecture and composable apps are following the same concepts at different levels of abstraction and use domain models as warrantors of the business core concepts.
-
-Does that mean domain-centric architecture is mandatory to use to build PBCs? Of course not. They come into play at different stages of your application lifecycle. But, if you find composable apps useful for designing your business application, there is no reason not to study these architectures to design your business code, too. And, if you already use domain-centric practices to build your apps, using composable apps could be a good move to streamline these practices for the different layers of your business implementation.
-
-Back to our survey application. Bob can definitely help us understand the business context, which helps to code PBCs using a domain-centric architecture and to design composable apps from a set of these PBCs. Thanks to Bob, we would be able to share that knowledge, through business components, with the company dev teams and let them reuse them.
-
-
-# Built for change
-
-Let’s admit it: we need experimentation to build great products. It is not possible to get it right on the first try (neither from a functional nor a technical perspective). So… if we have to make important changes many times, we have to build code that will welcome those changes!
-
-Types and Tests provide a pretty decent safety net to ensure that the solution is still working “as intended.” As we gain knowledge, the intent will change. New concepts will emerge, others will disappear. Code has to keep expressing that.
-
-With code built around a domain model, with really clear adaptations for its infrastructure, it is totally possible to refactor the whole thing without breaking anything! It is also possible to clearly extract a bounded context just by putting in a module (package in Java, namespace in C#, …).
-
-Moving bounded contexts into modules and letting them live there for a while is a good plan since it’s way easier to do (or undo) than building a dedicated binary with its infrastructure.
-
-This step-by-step plan is a good way to build a business-centric modular application that will be able to live and grow with your business!
diff --git a/vuepress/docs/_posts/2023-08-04-k8s-126.md b/vuepress/docs/_posts/2023-08-04-k8s-126.md
deleted file mode 100644
index 3966edaaa3..0000000000
--- a/vuepress/docs/_posts/2023-08-04-k8s-126.md
+++ /dev/null
@@ -1,18 +0,0 @@
----
-author: Entando
-date: 2023-08-04
-summary: Entando's policy is to support three active releases of Kubernetes. Support for each K8s release ends no sooner than three months after the official Kubernetes End of Life date to give our customers and partners time to upgrade their Kubernetes version. This blog post is an update related to Kubernetes 1.26.
-tags:
-- Entando 6.3.2
-- Entando 7.1
-- Entando 7.2
-- Product / Support
-title: Kubernetes 1.26 support for Entando 6 and 7
-cover: images/covers/entando-logo.png
----
-
-[Entando's policy](https://www.entando.com/page/en/eosl) is to support three active releases of Kubernetes. Support for each K8s release ends no sooner than three months after the official Kubernetes End of Life date to give our customers and partners time to upgrade their Kubernetes version. The Kubernetes official release timeline can be found at [https://kubernetes.io/releases/](https://kubernetes.io/releases/).
-
-The **active** and **supported** Kubernetes releases for Entando 6 and Entando 7 are now **1.24 - 1.26**. Please see the official [Entando Compatibility Statements](https://entando.com/page/en/compatibility-guide) for corresponding Entando patch versions and the [Entando Knowledge Base](https://entando.com/en/knowledge_base.page) (subscription required) for release notes and patch install instructions.
-
-Entando is available for any support requests at the following e-mail: [customersupport@entando.com](mailto:customersupport@entando.com).
diff --git a/vuepress/docs/_posts/2023-08-09-install-entando-with-docker-desktop.md b/vuepress/docs/_posts/2023-08-09-install-entando-with-docker-desktop.md
deleted file mode 100644
index 6361e7fbc5..0000000000
--- a/vuepress/docs/_posts/2023-08-09-install-entando-with-docker-desktop.md
+++ /dev/null
@@ -1,107 +0,0 @@
----
-author: Nathan Shaw
-date: 2023-08-09
-title: "Installing Entando for local development using Docker Desktop"
-summary: Setting up a local development environment and optimizing it for daily use is a critical task. Although most development tasks for Entando-compatible components do not require a local Entando instance, there are times when you want to test a new bundle and do not have a full remote cluster available. This blog post explores setting up a small cluster in Docker Desktop for this purpose.
-tags:
-- Local Development
-- Docker Desktop
-- Install
-- Entando 7.2
-cover: images/covers/2023-08-09-docker.png
----
-Setting up a local development environment and optimizing it for daily use is a critical task. Although most development tasks for Entando-compatible components do not require a local Entando instance, there are times when you want to test a new bundle and do not have a full remote cluster available. This blog post explores setting up a small cluster in [Docker Desktop](https://www.docker.com/products/docker-desktop/) for this purpose.
-
-There are numerous options available when setting up a local development environment using Kubernetes. Entando's [Getting Started Guide](../v7.2/docs/getting-started/README.md) makes use of [Multipass](https://multipass.run/) for this purpose but this approach isn't always possible, for instance, in some enterprise environments where Docker Desktop is allowed but direct use of Windows Subsystem for Linux is not. In this situation, enabling Kubernetes in Docker Desktop can be the simplest path forward.
-
->*Note:* The following steps were tested on Windows 11 with Docker Desktop (current at the time), including K8s 1.24.
-
-## Enable Kubernetes in Docker Desktop
-1. Start by enabling [Kubernetes in Docker Desktop](https://docs.docker.com/desktop/kubernetes/). In most cases this just involves enabling the option in the Docker Desktop UI and restarting Docker Desktop but there are some edge cases noted in the documentation.
-
->*Optional:* For local development, connecting the Entando CLI to your local cluster can be very useful. That can be done by [creating or selecting your ent profile](../v7.2/docs/getting-started/entando-cli.md) and then connecting your profile to the Kubernetes context using `ent profile link docker-desktop`. The following commands will reference `kubectl`, but as always this can be replaced by `ent kubectl` or the shorter `ent k`.
-
-2. Check that Kubernetes is up and running:
-``` bash
-kubectl get node
-```
-
->*Tip:* You can use [the standard Docker tutorial](https://www.docker.com/blog/how-kubernetes-works-under-the-hood-with-docker-desktop/) to setup a quick `LoadBalancer` and sample `Deployment`. Installing those resources in a dedicated namespace can make removing the resources later a simpler task.
-
-## Install the NGINX Ingress Controller
-Entando uses a small set of paths for the different services in an Entando Application so we'll need to install an ingress controller. We'll use the NGINX version since it is used in most of the [Entando install guides](../v7.2/tutorials/README.md)
-
-1. Enable the NGINX ingress controller [following the steps here](https://kubernetes.github.io/ingress-nginx/deploy/#docker-desktop):
-``` bash
-kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml
-```
-
-2. Access an arbitrary URL against localhost and you should now see an NGINX 404 error, for example, `http://localhost/some-path`.
-
-## Install Entando
-Many of the following steps are identical to those in the [Getting Started guide](../v7.2/docs/getting-started/README.md) so see that page for explanatory details.
-> *Note:* Make sure to check for the correct Entando patch version for the install steps since this blog post specifically documents the steps for Entando 7.2.2.
-
-1. Create the namespace:
-``` bash
-kubectl create namespace entando
-```
-
-2. Download the operator config map template:
-``` bash
-curl -sLO "https://raw.githubusercontent.com/entando/entando-releases/v7.2.2/dist/ge-1-1-6/samples/entando-operator-config.yaml"
-```
-
-3. Edit the file to select the NGINX ingress controller:
-``` yaml
-data:
- entando.ingress.class: "nginx"
-```
-
-4. Create the operator `ConfigMap`:
-``` bash
-kubectl apply -f entando-operator-config.yaml -n entando
-```
-
-5. Add the cluster resources:
-``` bash
-kubectl apply -f https://raw.githubusercontent.com/entando/entando-releases/v7.2.2/dist/ge-1-1-6/namespace-scoped-deployment/cluster-resources.yaml
-```
-
-6. Add the namespace resources:
-``` bash
-kubectl apply -n entando -f https://raw.githubusercontent.com/entando/entando-releases/v7.2.2/dist/ge-1-1-6/namespace-scoped-deployment/namespace-resources.yaml
-```
-
-7. Determine your IP address (YOUR-IP in step 9 below) using `hostname -I | awk '{print $1}'` or by visiting `https://whatismyip.com`.
-
-8. Download the Entando Application template
-``` bash
-curl -sLO "https://raw.githubusercontent.com/entando/entando-releases/v7.2.2/dist/ge-1-1-6/samples/entando-app.yaml"
-```
-
-9. Edit the template and set the ingressHostName to `entando.YOUR-IP.nip.io` or another address that will route to your local machine.
-> *Note:* Some connections from one pod to another will use a public address, rather than a cluster-level address. If the Component Manager and `entando-de-app` deployments fail to start correctly, this is the most likely cause. See the [tips and tricks page](../v7.2/docs/reference/local-tips-and-tricks.md) for troubleshooting tips. In my testing I realized my router had recently upgraded, blocking all port forwarding, so I had to re-enable that setting.
-
-10. Create the Entando Application resource which will start the installation process:
-``` bash
-kubectl apply -f entando-app.yaml -n entando
-```
-
-11. After 10 minutes or so, confirm your application is working. See the [Getting Started guide](../v7.2/docs/getting-started/README.md#next-steps) for additional next steps.
-
-## Observations
-I can see a few pros and cons for this configuration:
-
-*Pros*
-* Docker Desktop has broad adoption so making use of its built-in support for Kubernetes can be very straightforward.
-* Networking is a typical challenge for local Kubernetes environments but I didn't observe anything more difficult with this setup.
-* You can easily turn off Kubernetes (and come back to it later) by disabling the option in Docker Desktop.
-
-*Cons*
-* I didn't do a thorough comparison, but anecdotally Docker Desktop with Kubernetes consumes more resources, CPU and memory, than Entando's Multipass-based approach due to the overhead of Docker Desktop itself.
-* At least on Windows, the Multipass setup works seamlessly with Windows networking by automatically provisioning an `entando.mshome.net` address and mapping it to the Multipass VM. That can be a better experience, and often simpler from a network standpoint, then using an `.nip.io` address.
-* Since Multipass directly uses a single container, it's easier to take and restore snapshots of test instances there.
-
-## Next Steps
-It would be interesting to do a similar investigation using [Minikube](https://minikube.sigs.k8s.io/docs/), [kind](https://kind.sigs.k8s.io/), or [k3d](https://k3d.io/). There are numerous write ups in the broader community (e.g., [https://linuxconcept.com/comparing-minikube-kind-and-k3d] ) comparing resource usage, production-like qualities, and developer friendliness, but a review from an Entando perspective has not been done in a while. [Community](../v7.2/docs/community/contributing.md) contributions would be welcome here!
diff --git a/vuepress/docs/_posts/2023-08-14-streamlit.md b/vuepress/docs/_posts/2023-08-14-streamlit.md
deleted file mode 100644
index 313f9f9cbc..0000000000
--- a/vuepress/docs/_posts/2023-08-14-streamlit.md
+++ /dev/null
@@ -1,254 +0,0 @@
----
-author: Nathan Shaw
-date: 2023-08-15
-title: Deploying a Streamlit bundle in Entando
-summary: Streamlit is an open-source Python library which is very popular in the data science and machine learning community. It is useful for quickly creating and sharing beautiful data-driven web apps. There are excellent hosting options for public Streamlit apps, but in enterprise environments, there is a need for sharing such apps in a more controlled way. Entando provides a Kubernetes and cloud-friendly way to do this.
-tags:
-- Community
-- Developer Topics
-- Business-Driven Development
-- Entando 7.2
-- Open Source
-cover: images/covers/2023-08-15-streamlit.png
----
-
-
-# Overview
-[Streamlit](https://streamlit.io) is an open-source Python library which is very popular in the data science and machine learning community. It is useful for quickly creating and sharing beautiful data-driven web apps. There are excellent hosting options for public Streamlit apps, but in enterprise environments, there is a need for sharing such apps in a more controlled way. Entando provides a Kubernetes and cloud-friendly way to do this.
-
-## Create the Bundle
-1. Start by creating a new bundle for the `Streamlit` app:
-``` bash
-ent bundle init streamlit-example
-```
-
-2. Change into the bundle root folder:
-``` bash
-cd streamlit-example
-```
-
-3. Create a location in the bundle for the `Streamlit` app. In an Entando bundle, this means using a microservice to host the app. Use the [Entando CLI](../v7.2/docs/getting-started/entando-cli.md) to add a microservice for the Streamlit app:
-``` bash
-ent bundle ms add streamlit-ms --stack custom
-```
-
-4. Change into the `streamlit-ms` directory:
-``` bash
-cd microservices/streamlist-ms
-```
-
-## Create the Streamlit app
-Use the [Streamlit install steps](https://docs.streamlit.io/library/get-started/installation) to prepare the directory for Streamlit development.
-
-1. Add `venv` and activate it. This will keep the Python dependencies separated between projects.
-> The activate path may be different depending on your OS.
-``` bash
-python -m venv .venv
-source .venv/Scripts/activate
-```
-
-2. Use `pip` to install `streamlit`:
-``` bash
-pip install streamlit
-```
-
-3. Test `streamlit` to make sure it's working. Use CTRL+C to close the hello app.
-``` bash
-streamlit hello
-```
-
-4. Follow the `Streamlit` tutorial to [create a simple Uber visualization app](https://docs.streamlit.io/library/get-started/create-an-app).
-> Use a completely different application if you prefer, but the following steps assume the application is found in `streamlit_app.py`.
-``` python
-import streamlit as st
-import pandas as pd
-import numpy as np
-
-st.title('Uber pickups in NYC')
-
-DATE_COLUMN = 'date/time'
-DATA_URL = ('https://s3-us-west-2.amazonaws.com/'
- 'streamlit-demo-data/uber-raw-data-sep14.csv.gz')
-
-@st.cache_data
-def load_data(nrows):
- data = pd.read_csv(DATA_URL, nrows=nrows)
- lowercase = lambda x: str(x).lower()
- data.rename(lowercase, axis='columns', inplace=True)
- data[DATE_COLUMN] = pd.to_datetime(data[DATE_COLUMN])
- return data
-
-data_load_state = st.text('Loading data...')
-data = load_data(10000)
-data_load_state.text("Done! (using st.cache_data)")
-
-if st.checkbox('Show raw data'):
- st.subheader('Raw data')
- st.write(data)
-
-st.subheader('Number of pickups by hour')
-hist_values = np.histogram(data[DATE_COLUMN].dt.hour, bins=24, range=(0,24))[0]
-st.bar_chart(hist_values)
-
-# Some number in the range 0-23
-hour_to_filter = st.slider('hour', 0, 23, 17)
-filtered_data = data[data[DATE_COLUMN].dt.hour == hour_to_filter]
-
-st.subheader('Map of all pickups at %s:00' % hour_to_filter)
-st.map(filtered_data)
-```
-
-5. Start the application and confirm it's working as expected:
-``` bash
-streamlit run streamlit_app.py
-```
-
-## Prepare the Entando Bundle
-A few items need to be tweaked to run the Streamlit app in Kubernetes with Entando. Here we're following the [Streamlit Kubernetes guide](https://docs.streamlit.io/knowledge-base/tutorials/deploy/kubernetes) with a few tweaks specific to Entando.
-
-1. Use pip to create a `requirements.txt` to help when creating the Docker image:
-``` bash
-pip freeze > requirements.txt
-```
-
-2. Create the `Dockerfile` for the service. This is based on the `Streamlit` example and modified to run on port 8081 under the Entando-provided `SERVER_SERVLET_CONTEXT_PATH`.
-``` bash
-FROM python:3.8-slim
-
-RUN pip3 install --no-cache-dir --upgrade \
- pip \
- virtualenv
-
-RUN apt-get update && apt-get install -y \
- build-essential \
- software-properties-common \
- git
-
-WORKDIR /app
-
-COPY . /app
-
-ENV VIRTUAL_ENV=/app/venv
-RUN virtualenv ${VIRTUAL_ENV}
-RUN . ${VIRTUAL_ENV}/bin/activate && pip install -r /app/requirements.txt
-
-# Entando settings
-## Required port for microservices
-EXPOSE 8081
-## Context path is provided by the engine based on the bundle id
-ENV SERVER_SERVLET_CONTEXT_PATH=/default
-
-COPY run.sh /app
-ENTRYPOINT ["./run.sh"]
-```
-
-3. Setup an entrypoint script `run.sh`. This script is to used to start Streamlit and also includes some minor adjustments for Entando.
-``` bash
-#!/bin/bash
-
-APP_PID=
-stopRunningProcess() {
- # Based on https://linuxconfig.org/how-to-propagate-a-signal-to-child-processes-from-a-bash-script
- if test ! "${APP_PID}" = '' && ps -p ${APP_PID} > /dev/null ; then
- > /proc/1/fd/1 echo "Stopping ${COMMAND_PATH} which is running with process ID ${APP_PID}"
-
- kill -TERM ${APP_PID}
- > /proc/1/fd/1 echo "Waiting for ${COMMAND_PATH} to process SIGTERM signal"
-
- wait ${APP_PID}
- > /proc/1/fd/1 echo "All processes have stopped running"
- else
- > /proc/1/fd/1 echo "${COMMAND_PATH} was not started when the signal was sent or it has already been stopped"
- fi
-}
-
-trap stopRunningProcess EXIT TERM
-
-source ${VIRTUAL_ENV}/bin/activate
-
-BASEURLPATH=
-if [ -z "$SERVER_SERVLET_CONTEXT_PATH" ]
-then
- echo "Context path not set"
-else
- BASEURLPATH=" --server.baseUrlPath=$SERVER_SERVLET_CONTEXT_PATH"
-fi
-echo "BASEURLPATH: $BASEURLPATH"
-
-streamlit run /app/streamlit_app.py --server.port=8081 --logger.level=debug --browser.gatherUsageStats=False $BASEURLPATH & APP_ID=${!}
-
-wait ${APP_ID}
-```
-
-4. Add a `.dockerignore` file with one line, so the .venv files are not included in the eventual Docker image.
-> Add a similar line to your top-level `.gitignore` to avoid committing those files
-```
-.venv
-```
-
-5. Update the health check and custom commands in the `entando.json`:
-``` json
-"healthCheckPath": "/_stcore/health",
-"commands": {
- "build": "echo 'no build required'",
- "run": "streamlit run streamlit_app.py",
- "pack": "docker build -t streamlit-ms ."
-}
-```
-
-6. Change back to the bundle root directory and check that the run command works:
-``` bash
-ent bundle run streamlit-ms
-```
-
-## Deploy the Bundle to Entando
-You should now be able to [build, deploy, and install the bundle](../v7.2/tutorials/create/pb/publish-project-bundle.md) using the standard steps.
-
-
-
-::: warning
-### *Warning* Workaround Territory
-In Entando 7.2.2 (or earlier), the Streamlit service will start successfully but the health check built into the Component Manager will NOT recognize that it's healthy since Streamlit returns an HTML rather than a JSON response. Streamlit does not provide an option to customize the health check or provide a custom JSON endpoint, so short of using a reverse proxy, two manual steps are required after the bundle is installed. A fix for this is planned in a future release of Entando.
-
-> The bundle IDs in the following steps will vary if you cloned the project source.
-
-1. When the health check fails, Entando will rollback the install but it will only shutdown the Streamlit pod. Restart the Streamlit pod:
-``` bash
-kubectl scale deploy pn-3d37ebd9-2d0e3ade-nathanshaw-streamlit-ms-deployment --replicas=1
-```
-
-2. Entando will also remove the ingress path for the `streamlit-ms` service. Add this manually into the Entando default ingress.
-``` yaml
-- backend:
- service:
- name: pn-3d37ebd9-2d0e3ade-nathanshaw-streamlit-ms-service
- port:
- number: 8081
- path: /streamlit-example-3d37ebd9/streamlit-ms
- pathType: Prefix
-```
-
-3. Verify the service is working by accessing YOUR-HOST/SERVER_SERVLET_CONTEXT_PATH. The default path should show the Streamlit application.
-
-4. Adding `/_stcore/health` to the URL should show `ok` from the Streamlit health check.
-:::
-
-## Create a Streamlit widget
-Now that the service is working, you can create a simple Entando widget to display the Streamlit app embedded on a page. See the [Simple Widget Tutorial](../v7.2/tutorials/compose/widgets-fragments.md/) for the basic steps and the [Streamlit Embed documentation](
-https://docs.streamlit.io/streamlit-community-cloud/share-your-app/embed-your-app) for options to customize the embedded display.
-
-1. Go to `Components` → `Widgets` to create a simple widget. Make sure to update the path to match your service.
-``` html
-
-```
-
-2. Create a page and place the widget on that page:
-![drawing](./images/2023-08-15-streamlit-in-entando.png)
-
-## Reference
-* The [source code for this example](https://github.com/nshaw/202308-streamlit-example) can be found in GitHub.
-
diff --git a/vuepress/docs/_posts/2023-08-17-spring-boot-websockets.md b/vuepress/docs/_posts/2023-08-17-spring-boot-websockets.md
deleted file mode 100644
index 788ff42bf9..0000000000
--- a/vuepress/docs/_posts/2023-08-17-spring-boot-websockets.md
+++ /dev/null
@@ -1,293 +0,0 @@
----
-author: Nathan Shaw
-date: 2023-08-17
-title: Create a Spring Boot service with WebSockets enabled
-summary: WebSockets are frequently used for one-to-many communications involving many recipients. This blog post explores building a simple Spring Boot microservice with WebSockets support and then deploying it into Entando.
-tags:
-- Community
-- Developer Topics
-- Composable Applications
-- Entando 7.2
-cover: images/covers/2023-08-17-stomp-local-test.png
----
-
-I recently had an Entando user ask about [WebSocket](https://en.wikipedia.org/wiki/WebSocket) support in the Platform. WebSockets can be very useful for real time system updates, especially those involving one-to-many communications with many recipients.
-
-My stock answer to this kind of question is that it's a development detail and *should* work, but it's up to each team to implement and support it fully. WebSockets run on TCP so it's a safe answer but I was curious if there would be any issue when using WebSockets in an Entando-managed microservice. Short story, there isn't - but I figured I'd jot down some notes on the implementation. In this case I worked up a quick STOMP example so you'll see that reflected in the naming below.
-> *Note:* This post is more of an outline of the procedure, not a step-by-step tutorial, but the source code is linked at the bottom.
-
-## Setup the Entando Bundle
-1. Start by setting up an Entando bundle with a microservice stubbed out:
-``` bash
-ent bundle init stomp-example
-cd stomp-example
-ent bundle ms add spring-stomp-ms
-```
-
-2. Next I used the [Spring initializr](https://start.spring.io/) to create the microservice with Maven, Spring Boot 2.7.14, and Java 11. This is similar to the steps in our basic [Spring Boot tutorial](../v7.2/tutorials/create/ms/spring-boot-ms.md) with the addition of the WebSocket dependency.
-
-```
- Project=Maven
- Language=Java
- Spring Boot version=2.7.14
- Group=com.entando.example
- Artifact=spring-stomp-ms
- Name=spring-ms
- Description=Demo project for Spring Boot with Stomp
- Package name=com.entando.example.stomp
- Packaging=Jar
- Java=11
- Dependencies:
- #under WEB: Spring Web
- #under OPS: Spring Boot Actuator
- #under MESSAGING: WebSocket
-```
-![spring initializr](./images/2023-08-17-spring-init.png)
-
-3. Generate the service and unzip the output into the `microservices/spring-stomp-ms` directory.
-
-## Implement the STOMP service
-Next we need to implement the service endpoints. Here I used Baeldung's [Intro to WebSockets with Spring](https://www.baeldung.com/websockets-spring) tutorial for guidance, so refer to this page for additional details.
-
-1. Add dependencies to the `pom.xml`:
-``` xml
-
- org.springframework
- spring-websocket
-
-
-
- org.springframework
- spring-messaging
-
-
-
- com.fasterxml.jackson.core
- jackson-core
-
-
-
- com.fasterxml.jackson.core
- jackson-databind
-
-```
-
-2. Create `configuration/WebSocketConfig.java` to enable the broker and endpoints. In this case I've also added a CORS config (the setAllowedOrigins call) for test purposes, but this should be disabled in a production deployment, typically using appropriate application profiles.
-``` java
-@Configuration
-@EnableWebSocketMessageBroker
-public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
-
- @Override
- public void configureMessageBroker(MessageBrokerRegistry config) {
- config.enableSimpleBroker("/topic");
- config.setApplicationDestinationPrefixes("/app");
- }
-
- @Override
- public void registerStompEndpoints(StompEndpointRegistry registry) {
- registry.addEndpoint("/chat")
- //NOTE: this is not recommended for production use and should be replaced by dev/prod profiles
- .setAllowedOrigins("http://localhost:8081")
- .withSockJS();
- }
-}
-```
-
-3. Create `entity/Message.java` and `entity/OutputMessage.java` for the incoming and outgoing messages, respectively:
-``` java
-public class Message {
-
- private String from;
- private String text;
-
- public String getText() {
- return text;
- }
-
- public String getFrom() {
- return from;
- }
-}
-```
-
-``` java
-package com.entando.example.stomp.entity;
-
-public class OutputMessage {
-
- private String from;
- private String text;
- private String time;
-
- public OutputMessage(final String from, final String text, final String time) {
-
- this.from = from;
- this.text = text;
- this.time = time;
- }
-
- public String getText() {
- return text;
- }
-
- public String getTime() {
- return time;
- }
-
- public String getFrom() {
- return from;
- }
-}
-```
-
-4. Add `controller/ChatController.java` to map the chat messages to the message broker:
-``` java
-@Controller
-public class ChatController {
-
- @MessageMapping("/chat")
- @SendTo("/topic/messages")
- public OutputMessage send(final Message message) throws Exception {
-
- final String time = new SimpleDateFormat("HH:mm").format(new Date());
- return new OutputMessage(message.getFrom(), message.getText(), time);
- }
-}
-```
-
-5. Add the following two lines to `src/main/java/resources/application.properties` so the service will: 1) run on the conventional Entando port, and 2) use the standard healthcheck path.
-```
-server.port=8081
-management.endpoints.web.base-path=/api
-```
-
-6. From the bundle directory, start the service:
-``` bash
-ent bundle run spring-stomp-ms
-```
-
-7. Confirm the service is working as expected with two basic checks:
-* Access `http://localhost:8081/chat` which should show the text `Welcome to SockJS!`
-* Access `http://localhost:8081/api/health` which should respond with `{"status":"UP"}`.
-
-## Add an HTML page to test the service
-Here I followed the Baeldung tutorial and created a simple HTML page for testing the basic STOMP chat client.
-> *Note:* In a real implementation, the sockjs library can be included in a micro frontend (e.g., React, Angular, etc.), or an existing STOMP component can be reused (e.g., [react-stomp](https://www.npmjs.com/package/react-stomp)), but that is left as an exercise for the reader.
-
-1. Create `main/webapp/index.html`:
-``` html
-
-
- Chat WebSocket
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-```
-
-2. Go to `http://localhost:8081` to see a basic chat interface with options to connect to the service and send messages.
-
-3. Open two (or more) browser windows and observe the publish/subscribe behavior in action.
-> The browser console can be used to see the different STOMP messages due to console logging included in `stomp.js`. In Chrome, the network traffic can be observed by filtering on WS, selecting the WebSocket resource, and viewing the Messages pane for that socket.
-
-![chat messages](./images/2023-08-17-stomp-local-test.png)
-
-## Deploy the bundle to Entando
-You should now be able to [build, deploy, and install the bundle](../v7.2/tutorials/create/pb/publish-project-bundle.md) using the standard steps.
-
-
-
-## Test the live service
-1. Once the bundle is deployed, examine the ingress paths and check that the service is working correctly. The ingress path looks something like this:
-```
-http://YOUR-HOST/stomp-example-f9335a57/spring-stomp-ms/chat
-```
-
-2. Copy the `webapp/index.html` to a new file (e.g., `prod.html`) and update the serverUrl to point to your endpoint:
-``` javascript
-var serverUrl = 'https://YOUR-HOST/stomp-example-f9335a57/spring-stomp-ms/chat';
-```
-
-3. Access the new file at `http://localhost:8081/prod.html` and confirm the chat service is working.
-> *Note:* A CORS error will break the page if you did not include the WebConfig rule to allow access from `localhost:8081`.
-
-> *Note#2:* This step requires having the local service running to serve the HTML file but any web server will do, e.g., `serve -l 8081 microservices/spring-stomp-ms/src/main/webapp/`
-
-## Observations
-Implementing a basic chat client using Spring Boot 2, WebSockets, and Entando 7.2 was straightforward and fairly self-explanatory. Please feel free to [join the community](https://join.slack.com/t/entandocommunity/shared_invite/zt-g609owdv-2K~YRh8zrI6lqlWo4aFWUw) and ask questions if your experience is different!
-
-
-## Reference
-* [Source code](https://github.com/nshaw/202308-spring-stomp-example)
-* [Intro to WebSockets with Spring](https://www.baeldung.com/websockets-spring)
-* [What's the difference between STOMP and WebSockets](https://stackoverflow.com/questions/40988030/what-is-the-difference-between-websocket-and-stomp-protocols)
\ No newline at end of file
diff --git a/vuepress/docs/_posts/README.md b/vuepress/docs/_posts/README.md
new file mode 100644
index 0000000000..1665467a50
--- /dev/null
+++ b/vuepress/docs/_posts/README.md
@@ -0,0 +1 @@
+Place the blog files in this directory. The archived blog files are at PS/Docs and Tutorials/Archived-Blogs/
\ No newline at end of file
diff --git a/vuepress/docs/_posts/images/2022-04-22.png b/vuepress/docs/_posts/images/2022-04-22.png
deleted file mode 100644
index 5b5cb9d089b0504624b1f2bb04deae8e6534119f..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 105828
zcmd42Racx%6D~YB!2<+$3&DfS3>t!aa7_pd?mB4D;10nC55a=FLvR_~-Q5P)&GY_(
z?>pIRpH<6U)zxKv^}RYwRapibgA4-z0AS0>eo_YjP@n(+vJ*PeYY$!z-Z}t)$f~ON
zMf&CC1;814cz(5aa+#Txb946y0C@koXui0*eVw_ve~ir?`i?IQKou6}6ql6c6%@uLBqP<9Ev_9!M8yOK|6EwvYH4j7o7((lX1Tk!7tvz0y}h%txvytr
zipUe~;_lTyx;8bxS9|$SLtDS2f2FQ||3-m(x#W_?%$lTd8jSr?O!@Ikz|S&!9(8dHH>(dsria
zNIa=T+*kWNnQwXcT){YXe}&XjifShOBWg;khq&cpyL)GSV_F@&iipW+=oy%^3OWH~
z5tQ<&2s-i7hN;(s;d9MqtFN||1{yTW{*&}Erla}ht6
zkAp`b{aGe#C>0>SH!yj#w)+@gcwX6Ysh?#ahP3I#&}$gQ;i
z=AF8!3WmUv%B<<3U`?)4JJkEPt5(ycK+`xNgdh%#EeOglFdcXOz!ov`pSO5rVmvWyZzIZGg
zO-W!Ne#Alcmo2Kl?_#Y%2w&UYHKi&;v4@k3Pc?Alf3vRbjsg;DD#
zHzRQ1{rQc%zHtov9+sl^ROIU6*M53xFurQ{a0<)ny_vjRT~g5y`&I7K@Kf7q
zmm^9UBGom-m*M%-T-$Rh&A!l^uy<3zsO95^2&xTg4ii%c!wB`thiUObhj@(z<%3Xt4>
zghv?$$WBckh0oUSG%`D7ysnEgas}lSI2F_K>>g!&G5o@J>esbA;_NP;up9rXbJrfF
z10Ah2TLEDToe@4O%ds8&C}Y=0-PRHoC)tltdk&dUp}R7d%iMFq-!;5(UoBUGRq5hS
z{ec^ZW}*XL*+al@;>vO@92F-wt+Fs966kmsQw;w3;z|F=!W<}K3d$NS28t|xIWOv*
z&gh}T$hA@?!7TCg%H8=M20z<}`E%-c>Fr8_GDo50$oYR=?JtCFkn-LJl+)
z$gTEpwb=21ZgLO@u()x%Pv9l^-HbT
zwZWM-7B1$*gO6NMz+*Kruj34PmU(j)tSqbAcZK$co!vhAPTqE}Jhd>}g&Vae0X4{c$2roHNibauH48#H*Z66s{+8U#(c}r2^v_|B
zV-fX;Xtc)H-xasrdnDmBUxvs^9zVi*(~XEqwdDS!fLZ*j?uS(utEUZ)_*E#Xhnqtm+NjArZ}M={-|^X{tSm}(Q)(Uk}`=77)Xwk3Jhbf?jT00qs9
z>LhvDTWa6Z(QMvd^hU-^5r{>^u%BFw~d=^)ZQHt9$xh}r7(Zdy)dNHAsqb_Sgj5(Cbh|NiQQFwcY8pE0j$$hAO^gLHdc~E
z%_*~DY!_Lm8EGlPu78h;SI+n}R*QV|J{a66cVgzk|0NCmn%|aCuq~PhbNx>N28{f>
zYuik&tAL7ndkH(%WE4$Y?T(8rrgWgohm7udIE6@$thdU$&(znG)ht|vs@eK7sIwxe
z;NFg6cUkQsxNqvN6QpjJ8#eeYcSvBv5Gp{C-wn3=2^`w@L??tt;t7W>1!s}U-WZ3}
zmEYLCNmwL!h$8pJTeQ55R&2GN2jgSOVai{jbsy>|xGI|%6gr^3s6a=)k0@wY7J^ct
zLV*)W_ggN|vJ%%8-4ShPMhEvv`1JTCn;XZ4Vg&H;0hka796}lv)nMKt|4$=y#`fDx
zbG4YU=L$odtD7J`Ide3%`xRx`ghTh^#+_IuRqltJWj43GQmTjm*Nd%98Et3jTG-ml
zK=nGKgynR(W!K2PBcv@fz7|%kIl{AzoBpr*N~U*mf8JR0!XOhWA~Oj;3jYdyEBWpL
zxJWraLv&~1-rqXiHf&pcJ>8H3W2jLrbr8of>;R^T(A#
z5SE)46*3cxrIcErIshM<{)v%jCWbK#F)y0d0fcJ3A+
z955Glh~C#DKi)n2=gvz-mPwvq$!O2d=?c#8sV+>hV(QTXx`&==S&EA$2TpZPi
zT?;n@dAOJRSX!!Pc7j!4DtD~D?adX@8qB(!+d?B&dP%~KYFqQZhEQS;CnVZ0#XF5p
zMQF*8&6(534LH%+xRX#*o3`h*Uj9v7;;R&WDX+v>dlp!Th%un{d3pf5sjjxT8}sl{
z^CoMTG#akx2>FcurVyS%?D@Rre)1hU*>-r_4T%GnJm-m7h$VpGDG{)0%hLuUqDT$E
zoDysrC?*2pbX9WDhEK3K#9TafHSRuMUPkV|+C!$;)BOAWp@`%*dBW*{h(2`5qK#4P
zd;TyF{g35TA#PZy7kJjC_4kCkLK-m?+^ugbA1El#{%7lM>Jp2QYUoAF=el5#Q9kn~
z#!ex1){+qx_+6`H7xu4=F)(+izmRF8&dq`3PU
zr=Xb`X1uPQvv@02*7ah=7+-QhO61$t4E4~l%60e27An`_0>5MuINLN9uy@{wFATbawuH8W|*p4PB
zJ05Hr&yeulBu>Tm+IQp5J*ZB01GduMJ}wr^RK8q`)Q4yh_k&5rjyZ99)w0)Cgnt{$
zC&wMTic><#yrzAtRCX6ab}b{`d5=asbJZ&@k&Ab@{f;`O)h)UZe8>z_=>5yx7%4>I
z7)yd&%MIJ6kNcM0b3Ypv_UdqyMK5z2Ov^;NS4XG5RBur``ftHE&1XMq{8t}kQQx3P
z4vQZ5eLpPBl5QauXr;EJb4rCRWmgIdt!}+(6+jxT!BM(4Ns?D>0g~q^lh_(__rXgIr^$;+x2f*Ix=^IY}CoCStH!Ar1D2>Fdb}X-x=m@
zN2qP}FONBVMyS+vS{E$%CO=hsGTQ#&MC$^pVub8quT3DGLHAV2GzDyJLxeesNIPI4
zMd^+GT7$BSxKfQ9B_!tUBib!76SXjL{`g!sX9S{x`N_!AzD-$e+s%0wmE5
zi>r52hawoDRvro-cd6uOTU2&2^%p-LE^I$s?=%7@T{fY&niU%QB0KBl0n+G(e_!Wc
zY^xG8E(=VLe#^!S=6tlkyD-y<9J*MIdEdKPJvpVXWnC`tP?6@5q
zuce$+YWXb1bAJ)$N-kvs5^7u*z#1`BkG&9dwlZ5(gSzv=c0Jd>BNUAPt1fu{ax8Jj?Rd1za=z=y
z+$QQ>!5j&qC66eR6z<=Wp=Um`Z8YW7{Tv4D^_JKU*!P&JW;A|u)Uqyptq<{;^su{G
zG2a)fPO1W+A?KzCsqJKjx~j+EWFqxRa`>!wyGGh)N1z^@J3X;rQH?EX=0l-@uSkIv
zZLLqkSi)@Ld6}LZg$PKHdE^d4$~wf{BS;^_u~-7Pv6as7dr;cCL*J!%uHE!$Ko+@q
z@yWsGT-$zCE#l??=-wVKs0~+CsF3+Fv3c5&b3i4sT{0NWS^fpYyxciXO6#(3lnz#I
zd)C?^r41VM3wVv49Q#nz@}U0+?e6{8-nMswAo`#&X<>b6`B^+)5FVr!p0#xQ6w@_}
zLi5@RuHNxH#q|#2mPCJ2cuib*_iiSy`DKsJ@=X4}rf>{g1=dd80eoemYvGS4xrg{)
zE%U3i7htzSa-`^k3v9(4DGGOYj7iCJHg0Vc{6r8ylP+s=9jcpf!>luB{YQ5su~0vG
zv+!~LzQV_Ug7Et6p<|D0*q|K?rz`M3paqoe=K*y5kIcYt*CW_~q5bpK!rdYTto_7M
zXr5n|ykid&VrpD1xJfvW73vSG&4$px005aUM)3?wb03A?4tVhBjL`8v7=CH|Vz)^t
zJ$e-O`+rl=j-AB@s@PI5hW$oDu#9U~EJ<W5EFbK-YU4eZn5MP9)B~>Mt#qtCpbi>WKZiX^IpdEw|KIruXt9EptSRyDJv@
zrLs=5ho3^Me!S{IVKb3qCew!m6KQ7D*zrurkmj$;xQ#2i$WZ@aod0$-ZZvQB
z=BeiR0$AU@)0ONgN}uZuq-sx1tlyP_PUZm>P6W!2BR-4$7XEKH(GF|)GTSrCEmFXC
z;7k@6cJ6J{xZQV
zL^bPjXO3B5pO-%DB2I!+>oiCd-z(r%EkCe~%`k-Op8tt6PdR_sv1To(Z0-FNvAR8f
z25it7(Ux{l8@l=r=L$B0;F}}nhTFPnN(Ti(=bl`J+cr
zrCuRA4plS7d%1Y!#?z7cpAPu9jmgJfV{sC)T}$>aEx9Z;>%sO!hr#tVjbE1F_iX!F
zwEsCw@9yYi34)mJsH8;vZciCeT3`3566ZvK@-yF``c2vRt!eIA2)|x~^jlG(_Rp_U
zta|GRF^*B+%GGU=)D4&Zy!QOdHDr~*gs~jDsXU_&{-2MkF-mkrS$%D{`}6IH`RQZX
zOg`O07M{F1_J1aBXXxrwxIg_LNyPo+-Vb+oJNShPz(e=f`PJEO#QS(QfL-={`
zW}lQs9tMzupvq40h{r<_;xDmc^TGZMAS8y@A-Vr=Lt-MXY_Au50IvR32$={5oj)T8
ziEW?MyzBO$Fj)?iUxjt#w^#uG^{RB@v}X8{;wm9=(-WmA=?(OMgf1gF*3#W5MYligQ2f
zXh%-nUURqHGiqdNlC^#O{*DVfaJ#*AebuH}-a9!e#jBXl;ix>1?|E*YbX^080%LfA=x37U-O8lUZW4nNW-$EU}H5aUz=i}ecO+N#wb(}Tw-QgVLU%2
z*uQ!b9wnI3F|ixhf(9(*GYqxccn2_mje9^;@De_Ww(v9evI2u^u#cAf_wGTVtewZ$
z^8@5$N3%>%ZLM9u-2HRoC$x?7gZZ7T`DAFx7Z?+SpXAvQCudi0HMfQdxkqqIn}f;g
zNO%C@Qbg=*2nRH_m&&^J=)BkHX#!%+bfW0-xrN;=LV6v#+Xp}n
zs&v0r*+v;b{_8beM#jX4^Un<9@SFtlheJ;jwSzrz3PDI+BosTu4-@mr)_3>XCy)Qy
z#MW`=NIZ)CeG?7NVBj`XED8FMJW>>16U2U}b7@n^ENdqVsvr9y=yGY}^r~!oH|=F)
zU^&|$jf3j2nm%gyWy!HbXseBtV_pIjx)!VC_AOJGH84SYBmdCMc&9!d9Ge$9q%pX?
zm)`~Ai^BbQf?-8(2pgd-?<3C`)Ns1rVFn4rYVfX=A(&%$W=29Wn_p&g!J#h-G0=~P
zft59#6}X|ZJi~1Aps=Kj3hhe4Bz?ka!Hv`a<*38?lt}_~{eZ%Fa;tBdfnkC}u3Qri
z-uPBmC=4zHctmCI{XX3fm1(K=W6Ek#GkkAw=u9At;S<<8qx~~#rUp5AtVDN>?_b2;
zH`ZGv`qj!>G;-GyIb`^+LkIg8RF>AxN&aU=f{3`x7pH27+jq)^Fsz4VG8aSP@XIUQ
zFe*^iUj@_p^$#7WJ2bZVTbeXew{I41@93Yz(_Iv)6Le{`*^&JX^)Y
zS!l0DL>q)932XVg`ER*hD26+wm3?^E;?T-K#*7O?th3{?u@
z)iO?AkBfo~VWpP0@2B&<4WE;KLq7^NCGW>ftkGS@DcUiIZl3M2#iyOFvYvZX04)dZ
z52-lc(tb0$rwFq;roBCT1yE2#tuk++1e9fG!o`ooeUwfk(4xUP5X44X`uN$|Kf|Wg
zQQHuS((HuUgV3--#PqC|JpR6nj~a6LSMbaJnZgh0K?|4hO3$x{*x!k}2a3CJXJzy*
zhsA!hv2#wi#$ww>Ttx;4vbN)EY3*+MBuQV-8?-20qQ3^O)Z14T&VShztN6cl(ofDu
z34_9JAy_PESoO9Fd0rU4{E*(UlEP1XxI{lUI{%cUB#st|O+A(OYXxsVWZPSwITu~f
zwPy3>GwM=sv)LZbhss%@Pb&xJFLzTI)L(o!8gu4iF2I3?qFX}jQfj*pP8mW%
zWe>B<4oO3!>Ix=bHq24m+o8t>ARdmG*bPEjqX${WAuMAiZI>Wnx9A3OypQ8?^vZR(*y=+v|)l7
zpS98;^qG`upiHPoy;-
z??hFoaONkfakaS#v#`y%L%Ajr=$oJlSEqXM)Mzr%&?V+R!=xwQkm`BJ$_C?MCxnY3
zpB?pl=*m7Y{MTC~ompq+ijxS0XDlkGzJuOXE5q5#qpyN-%f{HkN8Dz_E-auFJ+iBE
z(O9pYyDJG9oC?#|8c6710isXkeL`t59vVj0xX+rHdzTs$eMs{X{Ls<%1`rU+J&P&F
ze$e|v@Q?zbqhYjtzun8h);Yxp4NyM$w`sfZvLy|G9F-b5Pi2g-Q8~ayBSxpR{BBXP$uTTn^tMnjc#mj7}9up!$0>f
zs&XL)BlWpmQ{;l(2|S_!z$}pcQRIA`^<&aoB1hKR>f%UfcU%w2SZ?s6>y}Z>Gv-z4
zdjSr&!^StrUZOviK6*Bv013uNmBBfgTV&&
z6n~e5b1`zN=~G-=(x!4_74!#Ns%l9Jt$c?n(VceW#PMcC|Zym!_0G{35dD4BzDGjw~O$TPi7Q!@vD`7$3!cp$~R02y&xA*MCIQG=E|SX
z`uc&|keP=pVi5TKjP0q;`v*ON*P|GQU=1|xz0{Utun*^(tPwRv?_5KXvuV!9W#Q0v
zJ0z`o)Ye3ceVnV3d7HX}jGzA`b%%L6IBic}&CGhzQtb^|MM}jOm=dD%XN!hrIt-7{
zL!Ax+=NRZ!AsnNiL&%JDiGA3ob0BUsHQ1?ANek9-`Dmj6iny$m>G^PJpme#kmhvNv
zhjc8g=U^WqDt@BNaWK2OW$kP~X2QI-2Dz5TfQQJ_vY1z%=_LCv@uoFsyvesOZfx`r^2-}IgC
z`Q+VOr`I19M;$}&TB(8|MB_X~PygiaIWZHn?ZaHuYH$siY%N{9#kiga^#8*jP9m13s
z2|bS*9%fL^?PtjPY-77kKc(GrTZt<*wgK;yqq~mh9293
zjCYs>!UYI58^Kykt9&vr2g_V=;8zu#a&W!;iZn*CqQ-g341eym5ue$6z0
z!NVgTy7{ksk|NZ3LB@Q&3Zv&c9*s*hwX4p;5yOI1?d4mWC
z!#8iKsm%tm8gqv8y!Fru)}{96e>k7J0fG)H1tD(I1t%f@r1g0O+E&sU5wuTXOFFj4
zI`v+mE
zru3UqD%n5D;H=XuFI4X2MS9wmHyfxNj&BAx8uUeGeB{b4)d+IZLuYtc<4<=)l-rMi=1rtOD1{8GbI-@w2nKb6Y>o
zToPB-wyk)*5xJ!@kS4BK;GfqFykJlHdrBk2uIM)bOrC+G7S8e9Jfie~kbE`&8bsnv
zJJ)hSP}|ks;`}zeG^Q`uZEVTu`@7b!)%D#qr=JaG8#jn;iXhUTWR_j0X6M7$uvp>Dqco9{#*8
z84k+Z)t2<{xY^i!+c_7kwx79F&3<_#VaPyib%KacT6zQ}KlXQfDPSZTYyRL&v^}J$o_aoyR=o8uzXehH|MfF=Rst;R|P;FRA3Bm!DY6cID2TZkAN=s|(a-
zV7efBu|Jrd%YL5okxjWJ&2FV7?U@<-ONw3YxnMSJhYTvElRhqj%~la%VNv4EGPKjr
zu=VsF=FCX)`WqgfcJQ5P&3v<0YQ|^pkgxB@dKzc*Ok(bdOe=)$C-QuTj&z7Y9LD^u
zbspPqzjM9TgbJvx$#7BCa0Pc1M!NSg&bKL>S?TM|5owmj^*)YT!6bA2MfSNH@#5c0
zHiItmPw#S`^1zDv>z|Iz6kTfVSjge4cq^q(=>e^Ticime~3YQ?>Ygc3rpVRqV$Nw
zuKhSo=4>J+pul%DW2>59MM1x*`8VUkE;KVg>1z#T?6uQY+_Gw7U2UnoCRGRG{v#zw
zN@bR35o(-W6jkbD=xlWxS8%zs
z$(_ZvL9|prNn*pj!dXo#qw;MLXZzk)Cuc0Eg-gbTR{~h6m1e=Zeb-AAVbiY6x~)od
zFe0;l7sONXAUw+|(<0mH1Pg|U4$0ZkgaYT~AKGxW7eiS8~O`eU`fKyo~1Oa2V9%u>Hk
zt%yAksyd=5UeuW7wp)I&6?YM$s{(OI*2g)
zV7B0$iajRbFkf$3d-Be+gu%=J)_;s7w1h3|T`DDpq
z1MwVwcuZ5sx&QY*MAl_LbTn-Vt#vgI
zxak2W5!V;1$n-Sb^;=~8G?$-Jg|P#@1mwftHoUq_ch=FuNBc!CypZ)JryUDj2O
z1M%#8vC&51GkdtqW4YqH&o8yL1pz;Yf5l7X3$(yYNN8PwahC#SCFGudJMjrbO1i_G
zqb$XYyW0%)!WT0fHTi5Ov!WT*4FhJ4zJHxd4QsaUo8%&h-X>r#DN`zAn-64Om-A$)
z;a6XuEd`#7k$0F2T=>n67wZy#4srRow|@RGxmb2g8ExNg+!twq`q!Br;P3wv3_uU_
zK=qIPf10rT1YA`7yQyECHbkaX`}wfGc4VrnM9U6`ZP8sH$YlTh)Z49A+`R_Y(yHsz
zieh7kayq=|_V7KiH)@|+)*U?Tb17YvV6-S`{M_R+*5zYo>L;;@+d@VTlOB?b56+Y`
zo?yfFE;B+tHr*9q#IJi`^)Vo~t7<9Yh^NJtT(jEG=
zaF01Vs;@32ziI#}wGdt`WwTEF?j+Z)SOlIl7fGn4Y$ViFvg7t=WbaFB-mm!rQE&Ad
z(oQ=ZPWrEpu{5Nh
z`@ng4zxlO1%Ci2UdrOODGA72js#PaXC-30teBi0*gMH$2YRc-)g)y~n(NL
z))u~48RX@GgMG-`!*^lX$8VUs@^b&q`9L&@Z}Bp1;wrSY#MahOsH+*D?30^--V}z0
z%RaHsTZ&KnJ#!`xfl@_h;YVyuC{KnLwlsozv>+Hgp>HnRpW(N9_|fZj36_*
zS2?pkLvP9V+XvDz9_#mi!=qAIDBJF>OQy2N6wcXfU%tsIs2=Y=T=Vb5zYH;ah1!Yh
za7`{Ae80J2G@bu6@r`@@bT-aQqugG(_>np%_EE9snLM!OUE8w6t&t5-F$Lpq7Ci#wg^3sfcwfbw%Y_4
z+nvg3oO3hj(>JcrF|#b1+#uSaqUW8WNJ@UxJFVWwhoHEzZzw)nR9zV(G`yRTqqhO|
z1nEcHUJP%!I!O^g)D<-~8-7XOoz}T>Kes*^m5PF&Yoj&l#0K>sp8xv4ulWf_Tv$jU
z*jk4M!AaX#n0`$Wy6r
zPi+IQbq`Z!rA}Pr{W6>Vg`1!B?a}bHUE7P^!^9q}b#nX`BF}U`n8Mogxx0mQ}?C;arwkiUs~N~okqjtKPa%ii2v!&ca^=!%3CXE
z_3HZBGPo1itQmC$Xj1~lwY2UQv8Q5+MtLXTVa07JpYMb_JexC4VSq*h1MYP}Epl20!BSxe?@QaJVWjH}hp=&+veP3HkI44gF#
z6PUB)jQHzpJocgAKsjdCjrtyLsum!#s5<<{jh&c-t7{2^+A~E=l?5XZ5jEJ5^}N@F
zmiOadq*S)2Xbk7{cZw03Z?Ql;{PPi~!)%y7n4`&(L4Qa8jp@NvLf%ZfSu=VPvWa5M
zfQ|k(HY0zCuEu@j>2B|xW5Q{yAi%tNcb&kze{QfSvtFFRKlW|QI*mb+r|FjkSQle0
zx{`LQS7@OyI~cZ<^@XD@mJQ=QJy4)+KYuo2+Y9rZ-Cm_7#m@#l>?@J?KhFX`<)Dg|
zV0+bThSa`zMPRZ%k9gl{t*cOG&&JTRySv(_nq;>Pi~Z3l?Z@xrDNqVIFVv3U)kNXJ
z4A+*F1(_tFiw-D02*An$%0JMM@l%FMR}nG6g6V;ivBSdoI<<40)b$kWo>)Sr6Q3+<
zJ?DpTtt(P40GmINro*I(@uUqj_U=vJ5%GwYt_P0yJewtKRas6ndrAxE4}1BaiNJ!A
zSHbYJ+|i{)qv}Ny%Hk!Avs;8qskQlsI~DQo&2l-7UDMJ?Gg19a2sEz)4<8M;VdX!r2)AVc4=G8p16*;F$
z^BsbVpocc(q^#B)`94}$m<^GmPh|ejMqFDVzTb?WgWyAkENTQ}js34O%loPIpv_v`
zS-%!VB;*F`>^>nHHA6eszT#Y-{mP^Mqlp>NCp@13CjOx@lXGlE~-0}7|;qcfat|N3HZYuJ`)a@-pU%~rzgvJ*mpE2)}%Y%N*4os?1VVjJ|zBqME5Qs6Ynm)e5F?PNe&enV=5&E~AvaJVpL<
zUFsZyWx~LMKqBDuzaH{9|VNa8E@~@Go`^Vu2spbepkN?mu7(g9KGg%Ze3Riv-1@ScvCwTbzeo(MIBgyM!4XSx2hhJ4+SCyUF04{
z2ma{b9^CHv-?mT*uQ?yxfT{G<6dW&o_USuRY>HgvgPeMD>`-mbtKqg-c+QBhNUaSt
zHOO0B6Zg#fEuH(XoI75t2`GQMR^I&rI}9a}W>8*IP`piq+g|7MX&$(5efUuspXl0%sEQJ~%Z@@BIa8?QeebFgh6t
zIo6?=O67JkBiVC0zyqAbtya{&zZ$+T#1+=%Rg=re-GzH7%@Rg4VKsyDywUSgI1YXX
zlkt@&xbc`Sr=X!jdJ7yebvfj|dp<|9DX}=vNt~6At+D=T@-bV}EyfpeLzb*h$L6Pq
zp5Y|Xss@({k*Rd5);FF0W%q~u+iR(LPM3sPU(UN6b$G;ny)3-^V
z88
z_|jm>bqVCCgH=dEy?PHCf*xaOAE|;&Pzexa=Ytu@Ee<0dwmJNmFgFE1u6ebUXvBN3kZfhR>H3
zyUs)tS8|%9O&7Xr&4?YsPvD@Uw&~J0G~@5=kNu89vYkJ}miOx>gFj<&M~36ObyD@+
z>6!#@7vsG0{GWxqAH7VLa|Oe!mG6EioqxvD)ET<+-oZ)~6h2ufT7S|GFTpPnO;;t6
zz?;@Bk<+Vl0IUWe7Xs#UA^#SPREN!=_P;d4U<)y4j7%cwHa0ig+F~;-{fW!y1p6
z&9eEnv;6gG8-gj4ne)k^1feSLp{9w*VzzfRM)$e=cWXTE0QFwyn4Dp9<$J8WoEViB
z2yd5Q0)7)ymU&&H_vu|t?kB2sQbkR#?wzwwXQeP~WANV!6I#*q0&sG-cFomV-o-CJ
zdM&9s0j@J9f{=wWuY9ZR3~DzSE{qSV!_B5^T#$wilLk{5hcjp5Yx%4q3(oFezyN~*=DUCL`@=Ci64?BbD);HdasFVLID
zxaV2e5JKLcfFgwE@Av~V?emR|Fg=QOCBsp+4d&3ZeXjUd7d~$-uW7eqCc>?A5iBo>
z@x1v{^p0BHO}teq>lHHJG=d48qXBFj)0rO~#gM=?iF+-ln=`)*Um);M`!pu5%2@86
z?P_A>kB`i`M|7G0Y@9gnuwI_$J6bK{1|!!Mii=GtI)}RW`6NCmd9$=N8{_u!Jx&-M#JLe)yNbG_d01KqE-!v^1to#&c&P)Fn)iConuLa$pKAvpns
zr0LM8+xv-l~jB+V97w*^CgA)9N^c3Vr&lSoCXS8G|LCbIzW6;pe&(
zI#JA#`Ent$0pjU{Z*}XZC+sY$T=_-BzqtYmIMc-a&5GhQOX%7FoSYCMtLAGuW;Z}PIy_O1x
zoR=I}-g7rWE9BVVJH27Vd7a}5qpshI!Q#&Ki>(^&o%LW%H%A|;4A<6u$S3k{N-SPt
z>=^u~%k8g;SQPD524dWOl+nrW1~tfYwlrvRRZw9c2lRMQ3Ku#_IU9$N&4qyPA6o{ShOWyttHq@jbjF${Y0Gj@xh+2uBh_z0-L6ZdoJ}oIti#TZ
zW_NrH?onsJeC72<@U3_s%i7&&zaR5^che)?WE__4Ta96IC!cS=k|r;&2CxY{o+Bz5
z_dO6O-XF>&FWmQ@e9Ze(r-9U|G~;43Q_97Z@wt3iQUo!$WAl*I{0|Dt8=l3Onukxz
zpf&4byLsxD5W^S$%ynu+SX+u_+=RYPnMPeCugQGBP>qg&o}-VWAIevkkrRJo!6OO}
z-ZPeL4z4x{Y13Y+Z~b%5`7~*BN>qyzmS3=E8G|mv!>v|oF+Q4QO=+efB6E3&?sA!2
zp+8WK+P~Cbe08{sYA=TtFc?U4MMI{r>Tvmo%YJ`&xX
zbKkg}uJn!8z+L?#2Y{6#{<%SUAY}t$PWvIja1|}GCDnKQ
zy*<4oq7U@ItTf$PZFKE|Dc$V2zfUYdf8028CjmxiggFwpHIgJ&to;s#eVcB-V`Hv<
z33s4EEfKb-$StvIaH1nl#-9cK@K6Re+R9=^qUL|kAMv5J@V0%C^PlbpF(n8@*EzU(
z=Dc|;E~n9*W5Omx&@r3*&ZZt!4!&yg0p&+f)2w`*TBzY4_txFLmi1b>1ao8-%Qz+$
zve=jRrP!!fgeF(z8>Hk5f`10-fj9j+nr?q@+Th>IF+D;)q#<85DI<6BG^UZ2`mnCn
zC6(WfK9C{?fcc{cb-$uBk1qd+HfsI+ArySdfKyKPtec-FU8|?e!SS%?&+|T*=3t$W
zGPh|c|K~JQ4Ii_eeF{J62)vgOAltpy0g>}IXRCKz
zLpl3cbfpD!7&J&Vaz&5Enj^WyS|ceOk2C$L?pC-Z>yTDi*R#m(MD*y6BBV}*T5Ybm
zzWf!;z0VjHtV}NK>OvRD-YG0nFa~^e@ZTlva<*B!>m_IH;_^q{9A;g+!=Lpp>hz5F
zWN$&WX*-IUuGZ(9nm~u`BbM3b0=sm&hga|3i|BOn>9Kp7jPfJmz@YA51t)Zi$WSQp
zB>nZO$p87@It_n~mdkSZlIQM_!j&m{sW9M+{7!e$v~V_#4*TICU88o+*~}-h`1(RG
z)FXL~Y8jKFbt%eM{NYZ9R{&4{CmDfGCf`z3Y$u0ElJH0Ke+YOI6e%CcuTUhFX##@}
z@zHVe*m24#(S9zku05%i&o3iLeGJ!-!lfxPf~w}QzJY4*jrE}bn4O*SkR(X5DwtN(
z-n{65(A1{=u%!ls261uEj`EWYzK1tnfv0evBd;Vfx}86#r6P(lUtqFS)DEc1_K2-Ck9WIRMi<)?zhBz&%QsQM7F
zikcDzCJve9wnyLn6TxDMgmdaxqV;Xe12WY`nHV$I_WZX^pz8pIvjYC^7$^ULNkbD1`QG^bABw_+9{*=b6V7plUcN
z!lk@?+aV^Bd1YioMQ$VS+MRZDycCF{v@*1f%ld-H_W^MIyCiqU*DQ36
z2L&T5Ow7MzYV{yi{$Cb;T-K7{a!X6g5@ZEc(#xq^*zNxSU_hV0ilM%xlN;t!(7T6i
z)I~d?38J6eP~w$E`t@R==bv
zewQ4o=dgfhQ$5G@0TP6(r<8?9c>czbof*!uoOQjZp7UfKEA-9;=O%4dk5NVBh7sp|
zjdpPy`6*d#LY{$V+7Ch362c(7taTU~c-AB4KJVHGc-976e=RUnK^QAaNt
z%q}U_X+}9wqfnvm04QZ_YOyB|unI=AJj7b31U;&zrM@so_Rr9d?>(PHr5LFs^?4&J
zaS_BB8Q;RQg#K-Yr7FTBB2Nc|2zQ9a(D4U}G##4<=sRC%jXFGZH>9Z=c806zQ>SDi
zZs0jgS`KSu-6v#)rC28lCCq)iGh1Mce&{`im|liuDQ%o-ap*nA$Qu7gTZ5=;Y6#2W
z#KN=JrA~0Je@;}#ZIz(BGKbJe|L7BV_N$cC_%&QT*H1