3333
3434/**
3535 * Server-Side Page Fragment Composition pattern demonstration.
36- *
37- * <p>This pattern demonstrates how to compose web pages from fragments
38- * delivered by different microservices. Each fragment is managed independently,
39- * allowing for modular development, deployment, and scaling.
40- *
36+ *
37+ * <p>This pattern demonstrates how to compose web pages from fragments delivered by different
38+ * microservices. Each fragment is managed independently, allowing for modular development ,
39+ * deployment, and scaling.
40+ *
4141 * <p>The key elements of this pattern include:
42+ *
4243 * <ul>
43- * <li><strong>Fragment Composition:</strong> Server assembles webpage from various fragments</li>
44- * <li><strong>Microservices:</strong> Each fragment managed by separate microservice</li>
45- * <li><strong>Scalability:</strong> Independent development, deployment, and scaling</li>
46- * <li><strong>Performance:</strong> Server-side assembly optimizes client performance</li>
47- * <li><strong>Consistent UX:</strong> Ensures cohesive user experience across fragments</li>
44+ * <li><strong>Fragment Composition:</strong> Server assembles webpage from various fragments
45+ * <li><strong>Microservices:</strong> Each fragment managed by separate microservice
46+ * <li><strong>Scalability:</strong> Independent development, deployment, and scaling
47+ * <li><strong>Performance:</strong> Server-side assembly optimizes client performance
48+ * <li><strong>Consistent UX:</strong> Ensures cohesive user experience across fragments
4849 * </ul>
49- *
50+ *
5051 * <p>In this demo, we simulate three microservices:
52+ *
5153 * <ul>
52- * <li><strong>HeaderService:</strong> Manages navigation and branding</li>
53- * <li><strong>ContentService:</strong> Manages main page content and personalization</li>
54- * <li><strong>FooterService:</strong> Manages footer content and promotional information</li>
54+ * <li><strong>HeaderService:</strong> Manages navigation and branding
55+ * <li><strong>ContentService:</strong> Manages main page content and personalization
56+ * <li><strong>FooterService:</strong> Manages footer content and promotional information
5557 * </ul>
5658 */
5759@ Slf4j
5860public class App {
5961
6062 /**
6163 * Main method demonstrating Server-Side Page Fragment Composition.
62- *
63- * <p>This demonstration shows how multiple microservices can be coordinated
64- * to generate complete web pages, emphasizing the independence and scalability
65- * of each service while maintaining a cohesive user experience.
66- *
64+ *
65+ * <p>This demonstration shows how multiple microservices can be coordinated to generate complete
66+ * web pages, emphasizing the independence and scalability of each service while maintaining a
67+ * cohesive user experience.
68+ *
6769 * @param args command line arguments (not used in this demo)
6870 */
6971 public static void main (String [] args ) {
7072 LOGGER .info ("=== Starting Server-Side Page Fragment Composition Demo ===" );
71-
73+
7274 try {
7375 // Initialize and demonstrate the pattern
7476 var demo = new App ();
7577 demo .runDemo ();
76-
78+
7779 LOGGER .info ("=== Server-Side Page Fragment Composition Demo Completed Successfully ===" );
78-
80+
7981 } catch (Exception e ) {
8082 LOGGER .error ("Demo execution failed" , e );
8183 System .exit (1 );
8284 }
8385 }
8486
85- /**
86- * Runs the complete demonstration of the Server-Side Page Fragment Composition pattern.
87- */
87+ /** Runs the complete demonstration of the Server-Side Page Fragment Composition pattern. */
8888 private void runDemo () {
8989 LOGGER .info ("Initializing microservices..." );
90-
90+
9191 // Create microservice instances
9292 // In a real system, these would be separate deployable services
9393 var headerService = new HeaderService ();
9494 var contentService = new ContentService ();
9595 var footerService = new FooterService ();
96-
96+
9797 LOGGER .info ("Microservices initialized:" );
9898 LOGGER .info (" - {}" , headerService .getServiceInfo ());
9999 LOGGER .info (" - {}" , contentService .getServiceInfo ());
100100 LOGGER .info (" - {}" , footerService .getServiceInfo ());
101-
101+
102102 // Create and configure composition service
103103 LOGGER .info ("Setting up composition service..." );
104104 var compositionService = new CompositionService ();
105-
105+
106106 // Register microservices with the composition service
107107 compositionService .registerService ("header" , headerService );
108108 compositionService .registerService ("content" , contentService );
109109 compositionService .registerService ("footer" , footerService );
110-
110+
111111 // Check health status
112112 LOGGER .info ("Health Status: {}" , compositionService .getHealthStatus ());
113-
113+
114114 // Demonstrate synchronous page composition for different page types
115115 demonstrateSynchronousComposition (compositionService );
116-
116+
117117 // Demonstrate asynchronous page composition
118118 demonstrateAsynchronousComposition (compositionService );
119-
119+
120120 // Demonstrate error handling
121121 demonstrateErrorHandling ();
122122 }
123123
124- /**
125- * Demonstrates synchronous page composition for various page types.
126- */
124+ /** Demonstrates synchronous page composition for various page types. */
127125 private void demonstrateSynchronousComposition (CompositionService compositionService ) {
128126 LOGGER .info ("\n --- Demonstrating Synchronous Page Composition ---" );
129-
130- var pageTypes = new String []{"home" , "about" , "contact" , "products" };
131-
127+
128+ var pageTypes = new String [] {"home" , "about" , "contact" , "products" };
129+
132130 for (var pageType : pageTypes ) {
133131 LOGGER .info ("Composing '{}' page..." , pageType );
134-
132+
135133 var startTime = System .currentTimeMillis ();
136134 var completePage = compositionService .composePage (pageType );
137135 var compositionTime = System .currentTimeMillis () - startTime ;
138-
139- LOGGER .info ("'{}' page composed in {}ms (size: {} characters)" ,
140- pageType , compositionTime , completePage .length ());
141-
136+
137+ LOGGER .info (
138+ "'{}' page composed in {}ms (size: {} characters)" ,
139+ pageType ,
140+ compositionTime ,
141+ completePage .length ());
142+
142143 // Log a sample of the composed page for verification
143144 var preview = getPagePreview (completePage );
144145 LOGGER .debug ("Page preview for '{}': {}" , pageType , preview );
145146 }
146147 }
147148
148- /**
149- * Demonstrates asynchronous page composition for improved performance.
150- */
149+ /** Demonstrates asynchronous page composition for improved performance. */
151150 private void demonstrateAsynchronousComposition (CompositionService compositionService ) {
152151 LOGGER .info ("\n --- Demonstrating Asynchronous Page Composition ---" );
153-
152+
154153 var pageType = "home" ;
155154 LOGGER .info ("Composing '{}' page asynchronously..." , pageType );
156-
155+
157156 var startTime = System .currentTimeMillis ();
158-
157+
159158 try {
160159 var futureResult = compositionService .composePageAsync (pageType );
161160 var completePage = futureResult .get (); // Wait for completion
162161 var compositionTime = System .currentTimeMillis () - startTime ;
163-
164- LOGGER .info ("Async '{}' page composed in {}ms (size: {} characters)" ,
165- pageType , compositionTime , completePage .length ());
166-
162+
163+ LOGGER .info (
164+ "Async '{}' page composed in {}ms (size: {} characters)" ,
165+ pageType ,
166+ compositionTime ,
167+ completePage .length ());
168+
167169 var preview = getPagePreview (completePage );
168170 LOGGER .debug ("Async page preview: {}" , preview );
169-
171+
170172 } catch (Exception e ) {
171173 LOGGER .error ("Async composition failed for page: {}" , pageType , e );
172174 }
173175 }
174176
175- /**
176- * Demonstrates error handling in the composition process.
177- */
177+ /** Demonstrates error handling in the composition process. */
178178 private void demonstrateErrorHandling () {
179179 LOGGER .info ("\n --- Demonstrating Error Handling ---" );
180-
180+
181181 // Create a new composition service without registered services
182182 var emptyCompositionService = new CompositionService ();
183-
183+
184184 try {
185185 LOGGER .info ("Attempting to compose page without registered services..." );
186186 emptyCompositionService .composePage ("test" );
187-
187+
188188 } catch (IllegalStateException e ) {
189189 LOGGER .info ("Expected error caught: {}" , e .getMessage ());
190190 LOGGER .info ("Error handling working correctly - services must be registered" );
191191 }
192-
192+
193193 // Demonstrate invalid service registration
194194 var validCompositionService = new CompositionService ();
195195 try {
196196 LOGGER .info ("Attempting to register invalid service type..." );
197197 validCompositionService .registerService ("invalid" , new Object ());
198-
198+
199199 } catch (IllegalArgumentException e ) {
200200 LOGGER .info ("Expected error caught: {}" , e .getMessage ());
201201 LOGGER .info ("Error handling working correctly - only valid service types accepted" );
@@ -212,16 +212,16 @@ private String getPagePreview(String completePage) {
212212 if (completePage == null || completePage .length () < 100 ) {
213213 return completePage ;
214214 }
215-
215+
216216 // Extract title and first bit of content for preview
217217 var titleStart = completePage .indexOf ("<title>" );
218218 var titleEnd = completePage .indexOf ("</title>" );
219-
219+
220220 if (titleStart != -1 && titleEnd != -1 ) {
221221 var title = completePage .substring (titleStart + 7 , titleEnd );
222222 return String .format ("Title: '%s', Length: %d chars" , title , completePage .length ());
223223 }
224-
224+
225225 return String .format ("HTML page, Length: %d chars" , completePage .length ());
226226 }
227- }
227+ }
0 commit comments