1 / 24

Apache Isis integrates with Apache Shiro for authentication and authorization

Apache Isis integrates with Apache Shiro for authentication and authorization. Isis’ quickstart archetype generates a simple “ ToDo ” webapp. ... with Isis using Apache Wicket as the underlying web framework.

toki
Download Presentation

Apache Isis integrates with Apache Shiro for authentication and authorization

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Apache Isis integrates with Apache Shiro for authentication and authorization Isis’ quickstart archetype generates a simple “ToDo” webapp... ... with Isis using Apache Wicket as the underlying web framework Isis also uses the JDO API for persistence; DataNucleus is the underlying implementation @javax.jdo.annotations.PersistenceCapable( identityType=IdentityType.DATASTORE) @javax.jdo.annotations.DatastoreIdentity( ... ) @javax.jdo.annotations.Version( ... ) @javax.jdo.annotations.Uniques({ ... }) @javax.jdo.annotations.Queries( { ... } publicclassToDoItem ... { ... }

  2. Isis’ quickstart archetype also generates a REST API that exposes all the domain applications functionality according to the Restful Objects specification (http://restfulobjects.org) The underlying framework used isJBoss’ RESTEasy Application menu items correspondto registered domain services isis.services = \ 10:dom.todo.ToDoItems,\ 20:app.ToDoItemAnalysis,\ dom.todo.ToDoItemContributions,\ app.ToDoItemAnalysisContributions,\ app.ToDoAppDashboard,\ services.ClockService,\ 30:webapp.prototyping.ToDoItemsFixturesService,\ 30:webapp.prototyping.DeveloperUtilities,\

  3. Menu items are derived from the domain service’s public action methods @Named("ToDos") publicclassToDoItems... { @MemberOrder(sequence = "1") public List<ToDoItem> notYetComplete() { ... } @MemberOrder(sequence = "2") public List<ToDoItem> complete() { ... } @MemberOrder(sequence = "3") publicToDoItemnewToDo( ... ) { ... } @MemberOrder(sequence = "4") public List<ToDoItem> allToDos() { ... } } Prompt form is derived from the domain service action’s method parameters publicclassToDoItems... { ... publicToDoItemnewToDo( final@Named("Description") @RegEx(validation = "\\w[@&:\\-\\,\\.\\+ \\w]*") String description, final@Named("Category") Category category, final@Named("Subcategory") Subcategory subcategory, final@Named("Due by") @OptionalLocalDatedueBy, final@Named("Cost") @OptionalBigDecimalcost) { ...} ... }

  4. Enums are rendered as drop downs publicstaticenum Category { Professional{ ... }, Domestic{ ... }, Other{ ... } publicabstract List<Subcategory> subcategories(); } Supporting choicesXxx() methodrefines the available choices publicclassToDoItems...{ ... publicList<Subcategory> choices2NewToDo( final String description, final Category category) { returnSubcategory.listFor(category); } ... } publicstaticenum Subcategory { // professional OpenSource, Consulting, Education, Marketing, // domestic Shopping, Housework, Garden, Chores, // other Other; publicstatic List<Subcategory> listFor(Category category) { ... } }

  5. Date parameters are automatically rendered with a date picker Default values for parameters can be computed ... ... with the domain object delegating to injected services as required publicclassToDoItems...{ ... publicLocalDate default3NewToDo() { returnclockService.now().plusDays(14); } ... privateClockServiceclockService; publicvoidinjectClockService( final ClockServiceclockService) { this.clockService = clockService; } } Parameters are assumed mandatory unless annotated otherwise Other declarative validation, such as regular expressions, can also be specified

  6. Invoking an action ... publicclassToDoItems...{ ... publicList<ToDoItem> notYetComplete() { ... returncontainer.allMatches( newQueryDefault<ToDoItem>(ToDoItem.class, "todo_notYetComplete", "ownedBy", currentUserName())); } ... } ... returns either a collection of objects(as shown), or a single object, or a value Clicking the icon navigates to the object... The user interface is derived entirely from the domain object model. Additional metadata provides layout hints

  7. The layout metadata is represented in JSON

  8. Layout metadata can be specified either using annotations or using a ClassName.layout.json file The layout metadata can be downloaded through a DeveloperUtilities domain service... publicclassDeveloperUtilitiesServiceDefault... { ... @Override publicClobdownloadLayout(Object domainObject) { ... } } ... and the layout refreshed without an application restart publicclassToDoItem ... { ... @CssClass("x-caution") publicList<ToDoItem> delete() { ... } } Individual members can bestyled using CSS .entityActions .cssMenuPanel .menuhli.x-caution a, li.x-caution a { background-color: #C94316; }

  9. Each object has a title to identify it to the user... publicclassToDoItem ... { ... public String title() { finalTitleBufferbuf = newTitleBuffer(); buf.append(getDescription()); if (isComplete()) { buf.append("- Completed!"); } else { if (getDueBy() != null) { buf.append(" due by", getDueBy()); } } returnbuf.toString(); } ... } ... and each object is also represented by an icon publicclassToDoItem ... { ... publicString iconName() { return"ToDoItem-" + (!isComplete() ? "todo" : "done"); } ... }

  10. Properties that are not disabled can be edited ... publicclassToDoItem ... { ... public String getDescription() { ... } publicvoidsetDescription(final String descr) { ... } ... } ... but disabled properties may not publicclassToDoItem ... { ... @Disabled(reason="Use action to update both category and subcategory") publicCategory getCategory() { ... } publicvoidsetCategory(final Category category) { ... } ... } publicclassToDoItem ... { ... @Hidden publicString getOwnedBy() { ... } ... } Properties (and other class members) can also be hidden Properties can be validated declaratively using annotations ... publicclassToDoItem ... { ... @RegEx(validation = "\\w[@&:\\-\\,\\.\\+ \\w]*") publicString getDescription() { ... } ... } publicclassToDoItem ... { ... publicString validateDueBy(final LocalDatedueBy) { if (dueBy == null) {returnnull;} returnisMoreThanOneWeekInPast(dueBy) ? "Due by date cannot be more than one week old" : null; } ... } ... or properties can be validated imperatively through a supporting validateXxx() method

  11. publicclassToDoItem ... { ... @Named("Done") publicToDoItem completed() { setComplete(true); ... returnthis; } ... } No-arg actions can be invoked directly... publicclassToDoItem ... { ... publicString disableCompleted() { returnisComplete()? "Already completed" : null; } ... } ... but any action can be disabled as required publicclassToDoItem ... { ... public ToDoItem add(final ToDoItem toDoItem) { getDependencies().add(toDoItem); returnthis; } ... } Actions taking args can also be invoked...

  12. ... a form prompts for the arguments to invoke the action. Autocomplete allows the user to lookup references to other objects publicclassToDoItem ... { ... publicList<ToDoItem> autoComplete0Add( final@MinLength(2) String search) { finalList<ToDoItem> list = toDoItems.autoComplete(search); list.removeAll(getDependencies()); list.remove(this); returnlist; } ... } publicclassToDoItem ... { ... @Bulk @Named("Done") publicToDoItem completed() { setComplete(true); ... returnthis; } ... } No-arg actions can also be invoked in bulk

  13. Contributed actions allow the object model to be decoupled; similar in intent to aspects or traits. They are implemented in domain services, but are rendered as if implemented by the object publicclassToDoItemAnalysisContributions... { ... @NotInServiceMenu @NotContributed(As.ASSOCIATION) @ActionSemantics(Of.SAFE) publicToDoItemsByCategoryViewModelanalyseCategory(finalToDoItem item) { returntoDoAppAnalysis.toDoItemsForCategory(item.getCategory()); } ... } Contributed properties also enable the object model to be decoupled publicclassToDoItemContributions... { ... @NotInServiceMenu @ActionSemantics(Of.SAFE) @NotContributed(As.ACTION) @Hidden(where=Where.ALL_TABLES) @Disabled(reason="Relative priority, derived from due date") public Integer priority(finalToDoItemtoDoItem) { ... } ... }

  14. Contributed collections are also available to decouple the object model publicclassToDoItemContributions... { ... @NotInServiceMenu @ActionSemantics(Of.SAFE) @NotContributed(As.ACTION) public List<ToDoItem> similarTo(finalToDoItemtoDoItem) { ... } ... } View models may optionally be developed to support specific use cases. publicclassToDoItemAnalysis... { ... @Named("By Date Range") publicList<ToDoItemsByDateRangeViewModel> toDoItemsByDateRange() { ... finalToDoItemsByDateRangeViewModelbyDateRange = getContainer().newViewModelInstance( ToDoItemsByDateRangeViewModel.class, dateRange.name()); ... } ... }

  15. Like entities, view models have properties, collections and may also have actions. They provide a memento to the framework so that they can be recreated with each interaction. packageorg.apache.isis.applib.ViewModel; ... publicclassToDoItemsByDateRangeViewModel implementsViewModel{ @Override publicString viewModelMemento() { ... } returngetDateRange().name(); } @Override publicvoidviewModelInit(String memento) { setDateRange(DateRange.valueOf(memento)); } ... } View models are particularly useful for the REST API, where the client and server may evolve independently. The view models in this case provide a stable API to the client.

  16. The @HomePage annotation(on one of the domain services’ actions) can be used to return adashboard view model. @Hidden publicclassToDoAppDashboardService...{ ... @ActionSemantics(Of.SAFE) @HomePage publicToDoAppDashboard lookup() { returnnewViewModelInstance(ToDoAppDashboard.class, ID); } } publicclassToDoAppDashboardimplements ViewModel{ publicList<ToDoItemsByCategoryViewModel> getAnalysisByCategory() { ... } public List<ToDoItemsByDateRangeViewModel> getAnalysisByDateRange() { ... } ... } Both objects and side-effect-free actions are bookmarkable @Bookmarkable publicclassToDoItem... { ... } publicclassToDoItems { ... @Bookmarkable @ActionSemantics(Of.SAFE) publicList<ToDoItem> notYetComplete() { ... } ... }

  17. Detection of concurrent edits automatically enforced through optimistic locking @javax.jdo.annotations.Version( strategy=VersionStrategy.VERSION_NUMBER, column="version") publicclassToDoItem ... { ... } Isis’ DomainObjectContainer is the one point of contact between the domain object and the framework publicclassToDoItems... { ... publicToDoItemnewToDo( ... ) { final String ownedBy = container.getUser().getName(); finalToDoItemtoDoItem = container.newTransientInstance(ToDoItem.class); toDoItem.setDescription(description); toDoItem.setCategory(category); toDoItem.setSubcategory(subcategory); toDoItem.setOwnedBy(userName); toDoItem.setDueBy(dueBy); toDoItem.setCost(cost); container.persist(toDoItem); returntoDoItem; } ... privateDomainObjectContainercontainer; publicvoidinjectDomainObjectContainer( finalDomainObjectContainer container) { this.container= container; } }

  18. The DomainObjectContainer is most commonly used as an abstraction over the object store, to create and persist objects, and to query objects. It can also be used to raise informational and warning messages to the user publicclassToDoItems... { ... publicList<ToDoItem> notYetComplete() { finalList<ToDoItem> items = container.allMatches( newQueryDefault<ToDoItem>( ToDoItem.class, "todo_notYetComplete", "ownedBy", currentUserName())); if(items.isEmpty()) { container.informUser( "All to-do items have been completed :-)"); } returnitems; } ... } Some actions – such as those to install test fixture data – can be annotated for prototyping purposes only. These are styled differently in the UI, and are suppressed when running in Wicket’s DEPLOYMENT mode. @Named("Prototyping") publicclassToDoItemsFixturesService ... { @Prototype public String installFixtures() { ... } ... }

  19. Isis’ authorization model maps access to class members (properties, collections and actions) to Apache Shiro permissions: inaccessible vs read-only vs read-write/invokable. Shiro in turn maps those permissions to roles [users] # user = password, role1, role2, role3, ... sven= pass,admin_role bob = pass,user_role,self-install_role ... [roles] # role = perm1, perm2, perm3, ... # perm in format: packageName:className:memberName:r,w user_role= *:ToDoItems:*:*,\ *:ToDoItem:*:* analysis_role = *:ToDoItemAnalysis:*:*,\ *:ToDoItemsByCategoryViewModel:*:*,\ *:ToDoItemsByDateRangeViewModel:*:*,\ *:ToDoAppDashboard:*:* self-install_role = *:ToDoItemsFixturesService:install:* admin_role = *

  20. Isis provides a configurable publishing service to integrate with other systems in the enterprise. Either the invocation of an action can be published, and/or the resultant changes to domain objects. Default implementations serialize the events as JSON, persisted to a database table. @PublishedObject(ToDoItemChangedPayloadFactory.class) publicclassToDoItem... { ... } publicclassToDoItemChangedPayloadFactoryimplementsPayloadFactory{ publicstaticclassToDoItemPayload extendsEventPayloadForObjectChanged<ToDoItem> { ... publicString getDescription() { ... } } publicEventPayloadpayloadFor(Object changedObject, ...) { … } } { "metadata" : { ... } "payload" : { "title" : ... "members" : { "changed" : { "value" : { "href" : "http://localhost:8080/restful/objects/TODO/L_2", }}}, "description" : { "value" : "Buy stamps", } } } }

  21. Isis provides a simple auditing service to record changes to objects. A default implementation saves to a database table. @Audited publicclassToDoItem... { ... } publicinterface AuditingService2 ... { publicvoid audit( String user, longcurrentTimestampEpoch, String objectType, String identifier, String propertyId, String preValue, String postValue); } TODO:L_1 by sven, complete: true -> false

  22. Isis’ Wicket viewer has an extensible architecture. Third-party components can plugin to provide, for example, an downloadable Excel spreadsheet. Another third-party component provides a calendar for any collection of objects that have date properties A further third-party component renders a map for any collection of objects that has a Location property (are “Locatable”) A further third-party component integrates the HighChart JS library to render barcharts graphs of collection of objects that have numeric properties

  23. Isis’ integration testing framework supports both developer (JUnit) or BDD (Cucumber) style testing Isis applications are built using Maven. The archetype configures a multi-module project that separates the domain object model (dom) module away from the fixtures, the integration testsand the webapp module.

  24. The user interface, while customizable, is derived entirely from the domain object model. This page shows an instance of the ToDoItem class. publicclassToDoItem ... { ... public String getDescription() { ... } public Category getCategory() { ... } publicSubcategory getSubcategory() { ... } publicbooleanisComplete() { ... } publicLong getVersionSequence () { ... } publicLocalDategetDueBy() { ... } publicBigDecimalgetCost() { ... } publicString getNotes() { ... } publicList<ToDoItem> getDependencies() { ... } public void complete() { ... } public void notYetComplete() { ... } publicvoid add(ToDoItem t) { ... } public void remove(ToDoItemt) { ... } public void duplicate () { ... } publicvoid delete() { ... } ... } Business rules can be defined declaratively(as here, on a property)... ... or business rules can be defined imperatively(as here, on an action) Associations between objects are made using autoComplete() supporting methods Most business logic resides in actions, which can perform arbitrary logic (including delegating to domain services injected into the object) Isis uses the JDO API for persistence; DataNucleus is the underlying implementation

More Related