שירותי מיקרו עם אורקל הלידון

1. סקירה כללית

הלידון היא מסגרת המיקרו-שירות החדשה של ג'אווה שנפתחה לאחרונה על ידי אורקל. נעשה בו שימוש פנימי בפרויקטים של אורקל בשם J4C (Java for Cloud).

במדריך זה נסקור את המושגים העיקריים של המסגרת ואז נעבור לבנות ולהפעיל מיקרו-שירות מבוסס הלידון.

2. מודל תכנות

כַּיוֹם, המסגרת תומכת בשני מודלים של תכנות לכתיבת מיקרו-שירותים: הלידון SE והלידון MP.

בעוד ש- Helidon SE נועד להיות מסגרת מיקרו התומכת במודל התכנות תגובתי, לעומת זאת, הלידון MP הוא זמן ריצה של Eclipse MicroProfile המאפשר לקהילת EE בג'קרטה להפעיל מיקרו-שירותים בצורה ניידת.

בשני המקרים, מיקרו-שירות Helidon הוא יישום Java SE המפעיל שרת HTTP רזה מהשיטה הראשית.

3. הלידון SE

בחלק זה נגלה בפרטים נוספים את המרכיבים העיקריים של הלידון SE: WebServer, Config, and Security.

3.1. הגדרת השרת

כדי להתחיל עם ממשק API של WebServer, עלינו להוסיף את התלות הנדרשת ל- Maven pom.xml קוֹבֶץ:

 io.helidon.webserver הלידון-שרת אינטרנט 0.10.4 

כדי לקבל יישום אינטרנט פשוט, אנו יכולים להשתמש באחת משיטות הבנייה הבאות: WebServer.create (serverConfig, ניתוב) או רק WebServer.create (ניתוב). האחרון לוקח תצורת שרת ברירת מחדל המאפשרת לשרת לפעול ביציאה אקראית.

הנה יישום אינטרנט פשוט הפועל ביציאה מוגדרת מראש. רשמנו גם מטפל פשוט שיגיב בהודעת ברכה לכל בקשת HTTP עם '/לברך' נתיב ו לקבל שיטה:

main main static public (String ... args) זורק חריג {ServerConfiguration serverConfig = ServerConfiguration.builder () .port (9001) .build (); ניתוב ניתוב = Routing.builder () .get ("/ שלום", (בקשה, תגובה) -> response.send ("שלום עולם!")). Build (); WebServer.create (serverConfig, routing) .start () .thenAccept (ws -> System.out.println ("השרת התחיל ב: // localhost:" + ws.port ())); }

השורה האחרונה היא להפעיל את השרת ולהמתין להגשת בקשות HTTP. אבל אם נפעיל את קוד הדוגמה הזה בשיטה הראשית, נקבל את השגיאה:

חריג בשרשור "ראשי" java.lang.IllegalStateException: לא נמצא יישום עבור SPI: io.helidon.webserver.spi.WebServerFactory

ה שרת אינטרנט הוא למעשה SPI, ועלינו לספק יישום זמן ריצה. כַּיוֹם, הלידון מספק את NettyWebServer יישום שמבוסס על Netty Core.

הנה התלות של Maven ליישום זה:

 io.helidon.webserver helidon-webserver-netty 0.10.4 זמן ריצה 

כעת נוכל להריץ את היישום הראשי ולבדוק שהוא פועל על ידי הפעלת נקודת הקצה שהוגדרה:

// localhost: 9001 / שלום

בדוגמה זו הגדרנו את היציאה ואת הנתיב באמצעות דפוס הבנאי.

הלידון SE מאפשר גם שימוש בתבנית תצורה שבה נתוני התצורה מסופקים על ידי תצורה ממשק API. זה נושא הסעיף הבא.

3.2. ה תצורה ממשק API

ה תצורה API מספק כלים לקריאת נתוני תצורה ממקור תצורה.

הלידון SE מספק יישומים עבור מקורות תצורה רבים. יישום ברירת המחדל מסופק על ידי הלידון-קונפיג כאשר מקור התצורה הוא application.properties קובץ שנמצא מתחת לשביל הכיתה:

 io.helidon.config helidon-config 0.10.4 

כדי לקרוא את נתוני התצורה, עלינו רק להשתמש בבונה ברירת המחדל אשר כברירת מחדל לוקח את נתוני התצורה application.properties:

Config config = Config.builder (). Build ();

בואו ניצור application.properties קובץ תחת src / main / resource ספריה עם התוכן הבא:

server.port = 9080 web.debug = נכון web.page-size = 15 user.home = C: / משתמשים / אפליקציה

כדי לקרוא את הערכים אנו יכולים להשתמש ב- Config.get () שיטה ואחריו ליהוק נוח לסוגי Java המתאימים:

port port = config.get ("server.port"). asInt (); int pageSize = config.get ("web.page-size"). asInt (); ניפוי בוליאני = config.get ("web.debug"). asBoolean (); מחרוזת userHome = config.get ("user.home"). AsString ();

למעשה, בונה ברירת המחדל טוען את הקובץ שנמצא הראשון בסדר עדיפות זה: application.yaml, application.conf, application.json ו- application.properties. שלושת הפורמט האחרון זקוק לתלות תצורה קשורה נוספת. לדוגמה, כדי להשתמש בפורמט YAML, עלינו להוסיף את התלות הקשורה לתצורת ה- YAML:

 io.helidon.config helidon-config-yaml 0.10.4 

ואז, אנו מוסיפים application.yml:

שרת: יציאה: 9080 אינטרנט: ניפוי באגים: גודל עמוד אמיתי: 15 משתמש: בית: C: / משתמשים / אפליקציה

באופן דומה, כדי להשתמש ב- CONF, שהוא פורמט פשוט של JSON, או בפורמטים JSON, עלינו להוסיף את התלות של הלידון-קונפיג-הוקון.

שים לב שניתן לבטל את נתוני התצורה בקבצים אלה על ידי משתני סביבה ומאפייני Java System.

אנו יכולים גם לשלוט בהתנהגות ברירת המחדל של הקבלנים על ידי השבתת משתנה הסביבה ומאפייני המערכת או על ידי ציון מפורש של מקור התצורה:

ConfigSource configSource = ConfigSources.classpath ("application.yaml"). Build (); Config config = Config.builder () .disableSystemPropertiesSource () .disableEnvironmentVariablesSource () .sources (configSource) .build ();

בנוסף לקריאת נתוני התצורה ממסלול הכיתה, אנו יכולים להשתמש גם בשתי תצורות מקורות חיצוניות, כלומר ה- git ו- etcd configs. לשם כך אנו זקוקים לתלות הלידון-קונפיג-גיט והלידון-גיט-וכו '.

לבסוף, אם כל מקורות התצורה הללו אינם מספקים את הצורך שלנו, הלידון מאפשר לנו לספק יישום עבור מקור התצורה שלנו. לדוגמא, אנו יכולים לספק יישום שיכול לקרוא את נתוני התצורה ממסד נתונים.

3.3. ה ניתוב ממשק API

ה ניתוב API מספק את המנגנון שבו אנו קושרים בקשות HTTP לשיטות Java. אנו יכולים להשיג זאת באמצעות שיטת הבקשה ונתיב כקריטריונים תואמים או RequestPredicate התנגד לשימוש בקריטריונים נוספים.

לכן, כדי להגדיר נתיב, אנו יכולים פשוט להשתמש בשיטת HTTP כקריטריונים:

ניתוב ניתוב = Routing.builder () .get ((בקשה, תגובה) -> {});

לחלופין נוכל לשלב את שיטת HTTP עם נתיב הבקשה:

ניתוב ניתוב = Routing.builder () .get ("/ path", (בקשה, תגובה) -> {});

אנחנו יכולים גם להשתמש ב- RequestPredicate לשליטה רבה יותר. לדוגמה, אנו יכולים לבדוק כותרת קיימת או את סוג התוכן:

ניתוב ניתוב = Routing.builder () .post ("/ save", RequestPredicate.whenRequest () .containsHeader ("header1") .containsCookie ("cookie1") .accepts (MediaType.APPLICATION_JSON) .containsQueryParameter ("param1"). hasContentType ("application / json"). thenApply ((בקשה, תגובה) -> {}). אחרת ((בקשה, תגובה) -> {})) .build ();

עד עכשיו סיפקנו מטפלים בסגנון פונקציונלי. אנחנו יכולים גם להשתמש ב- שֵׁרוּת שיעור המאפשר כתיבת מטפלים בצורה מתוחכמת יותר.

אז בואו ניצור תחילה מודל לאובייקט שאיתו אנו עובדים, ה- סֵפֶר מעמד:

ספר בכיתה ציבורית {מזהה מחרוזת פרטי; שם מחרוזת פרטי; סופר מחרוזת פרטי; דפי שלם פרטיים; // ...}

אנו יכולים ליצור שירותי REST עבור סֵפֶר בכיתה על ידי יישום ה- Service.update () שיטה. זה מאפשר להגדיר את תצוגת נתיבי המשנה של אותו משאב:

שירות יישומי BookResource ממחלקה ציבורית {BookManager bookmanager פרטי = BookManager חדש (); @ עקוב על עדכון הריק הציבורי (כללי Routing.Rules) {rules .get ("/", זה :: ספרים) .get ("/ {id}", זה :: bookById); } ספר ריק ריק פרטיById (ServerRequest serverRequest, ServerResponse serverResponse) {String id = serverRequest.path (). param ("id"); ספר ספרים = bookManager.get (id); JsonObject jsonObject = מתוך (ספר); serverResponse.send (jsonObject); } ספרי חלל פרטיים (ServerRequest serverRequest, ServerResponse serverResponse) {רשימת ספרים = bookManager.getAll (); JsonArray jsonArray = מתוך (ספרים); serverResponse.send (jsonArray); } // ...}

הגדרנו גם את סוג המדיה כ- JSON, ולכן אנו זקוקים לתלות של הלידון-שרת-אינטרנט json למטרה זו:

 io.helidon.webserver helidon-webserver-json 0.10.4 

סוף כל סוף, אנו משתמשים ב- להירשם() שיטת ה- ניתוב בונה לאגד את נתיב השורש למשאב. במקרה הזה, שבילים מוגדר על ידי השירות מקודמות על ידי נתיב השורש:

ניתוב ניתוב = Routing.builder () .register (JsonSupport.get ()) .register ("/ books", BookResource חדש ()) .build ();

כעת אנו יכולים להפעיל את השרת ולבדוק את נקודות הקצה:

// localhost: 9080 / ספרים // localhost: 9080 / ספרים / 0001-201810

3.4. בִּטָחוֹן

בחלק הזה, אנו הולכים לאבטח את המשאבים שלנו באמצעות מודול האבטחה.

נתחיל בהכרזה על כל התלות הדרושה:

 io.helidon.security helidon-security 0.10.4 io.helidon.security helidon-security-provider-http-auth 0.10.4 io.helidon.security helidon-security-integration-webserver 0.10.4 

תלות הלידון-אבטחה, הספק האבטחה-הלידון-http-auth ו- helidon-security-integration-web-server זמינות מ Maven Central.

מודול האבטחה מציע לספקים רבים לאימות והרשאה. לדוגמא זו נשתמש בספק האימות הבסיסי של HTTP כיוון שזה פשוט למדי, אך התהליך עבור ספקים אחרים כמעט זהה.

הדבר הראשון לעשות הוא ליצור בִּטָחוֹן למשל. אנחנו יכולים לעשות את זה גם מבחינה תכנותית לשם פשטות:

מיפוי משתמשים = // ... UserStore store = user -> Optional.ofNullable (users.get (user)); HttpBasicAuthProvider httpBasicAuthProvider = HttpBasicAuthProvider.builder () .realm ("myRealm") .subjectType (SubjectType.USER) .userStore (חנות) .build (); אבטחת אבטחה = Security.builder () .addAuthenticationProvider (httpBasicAuthProvider) .build ();

או שאנחנו יכולים להשתמש בגישת תצורה.

במקרה זה, נכריז על כל תצורת האבטחה ב- application.yml קובץ שאנו טוענים דרך תצורה ממשק API:

#Config 4 אבטחה ==> ממופה לאבטחת אובייקט אבטחה: ספקים: - http-basic-auth: realm: "הלידון" סוג-עיקרי: USER # יכול להיות USER או SERVICE, ברירת המחדל היא משתמשים של USER: - כניסה: "user" סיסמא: תפקידים "משתמש": ["ROLE_USER"] - כניסה: סיסמה "מנהל": תפקידים "מנהל": ["ROLE_USER", "ROLE_ADMIN"] #Config 4 שילוב שרת אינטרנט אבטחה ==> ממופה לאובייקט WebSecurity שרת: securityDefaults: אימות: נתיבים אמיתיים: - נתיב: "/ משתמש" שיטות: ["קבל"] תפקידים מותרים: ["ROLE_USER", "ROLE_ADMIN"] - נתיב: "/ admin" שיטות: ["קבל"] תפקיד מותר: ["ROLE_ADMIN"]

וכדי לטעון את זה, אנחנו צריכים רק ליצור a תצורה ואז אנו קוראים Security.fromConfig () שיטה:

Config config = Config.create (); אבטחת אבטחה = Security.fromConfig (config);

ברגע שיש לנו את בִּטָחוֹן למשל, ראשית עלינו לרשום אותו ב- שרת אינטרנט משתמש ב WebSecurity.from () שיטה:

ניתוב ניתוב = Routing.builder () .register (WebSecurity.from (אבטחה) .securityDefaults (WebSecurity.authenticate ())) .build ();

אנחנו יכולים גם ליצור WebSecurity למשל ישירות באמצעות גישת התצורה שלפיה אנו טוענים הן את האבטחה והן את תצורת שרת האינטרנט:

ניתוב ניתוב = Routing.builder () .register (WebSecurity.from (config)) .build ();

כעת אנו יכולים להוסיף כמה מטפלים עבור /מִשׁתַמֵשׁ ו / מנהל נתיבים, הפעל את השרת ונסה לגשת אליהם:

ניתוב ניתוב = Routing.builder () .register (WebSecurity.from (config)) .get ("/ user", (בקשה, תגובה) -> response.send ("שלום, אני הלידון SE")) .get ("/ admin", (בקשה, תגובה) -> response.send ("שלום, אני הלידון SE")) .build ();

4. חבר הפרלמנט של הלידון

Helidon MP הוא יישום של Eclipse MicroProfile וגם מספק זמן ריצה להפעלת מיקרו-שירותים מבוססי MicroProfile.

מכיוון שכבר יש לנו מאמר על Eclipse MicroProfile, נבדוק את קוד המקור ונשנה אותו להפעלה ב- Helidon MP.

לאחר בדיקת הקוד, נסיר את כל התלות והתוספים ונוסיף את התלות של הלידון MP לקובץ POM:

 io.helidon.microprofile.bundles helidon-microprofile-1.2 0.10.4 org.glassfish.jersey.media jersey-media-json-binding 2.26 

התלות המחייבת הלידון-מיקרו-פרופיל 1.2 וג'רזי-מדיה-ג'סון זמינות ממייבן סנטרל.

הַבָּא, נוסיף את שעועית.קסמל קובץ תחת src / main / resource / META-INF מַדרִיך עם התוכן הזה:

בתוך ה LibraryApplication מחלקה, לעקוף getClasses () שיטה כדי שהשרת לא יסרוק אחר משאבים:

סט הציבורי של @Override getClasses () {return CollectionsHelper.setOf (BookEndpoint.class); }

לבסוף, צור שיטה עיקרית והוסף קטע קוד זה:

ראשי ריק סטטי ציבורי (String ... args) {Server server = Server.builder () .addApplication (LibraryApplication.class) .port (9080) .build (); server.start (); }

וזה הכל. כעת נוכל להפעיל את כל משאבי הספר.

5. מסקנה

במאמר זה בחנו את המרכיבים העיקריים של הלידון, והראינו גם כיצד להגדיר את הלידון SE ו- MP. מכיוון שמלידון MP הוא רק זמן ריצה של Eclipse MicroProfile, אנו יכולים להפעיל באמצעותו כל מיקרו-שירות מבוסס MicroProfile קיים.

כמו תמיד, את הקוד של כל הדוגמאות לעיל ניתן למצוא ב- GitHub.