http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/booking/routing/AssignCargoToRoute.java ---------------------------------------------------------------------- diff --git a/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/booking/routing/AssignCargoToRoute.java b/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/booking/routing/AssignCargoToRoute.java deleted file mode 100644 index e3fd181..0000000 --- a/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/booking/routing/AssignCargoToRoute.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * - */ -package org.apache.zest.sample.dcicargo.sample_b.context.interaction.booking.routing; - -import java.time.Duration; -import java.time.Instant; -import java.time.LocalDate; -import org.apache.zest.api.injection.scope.This; -import org.apache.zest.api.mixin.Mixins; -import org.apache.zest.api.value.ValueBuilder; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.booking.exception.RoutingException; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.booking.exception.UnsatisfyingRouteException; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.booking.specification.DeriveUpdatedRouteSpecification; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.exception.InspectionException; -import org.apache.zest.sample.dcicargo.sample_b.data.factory.exception.CannotCreateRouteSpecificationException; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.cargo.Cargo; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.cargo.RouteSpecification; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.Delivery; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.NextHandlingEvent; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.TransportStatus; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.handling.HandlingEvent; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.itinerary.Itinerary; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.voyage.CarrierMovement; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.voyage.Voyage; -import org.apache.zest.sample.dcicargo.sample_b.infrastructure.dci.Context; -import org.apache.zest.sample.dcicargo.sample_b.infrastructure.dci.RoleMixin; - -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.RoutingStatus.ROUTED; -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.TransportStatus.CLAIMED; -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.TransportStatus.NOT_RECEIVED; -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.TransportStatus.ONBOARD_CARRIER; -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.handling.HandlingEventType.LOAD; -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.handling.HandlingEventType.RECEIVE; -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.handling.HandlingEventType.UNLOAD; - -/** - * Assign Cargo to Route (subfunction use case) - * - * The booking application presents some routes that the cargo can take and the Cargo Owner chooses - * a preferred route that we then assign to the cargo here. - * - * This is step 4 in the Route Cargo use case. - */ -public class AssignCargoToRoute extends Context -{ - private CargoInspectorRole cargoInspector; - - private RouteSpecification routeSpecification; - private TransportStatus transportStatus; - private HandlingEvent lastHandlingEvent; - - private Itinerary itinerary; - - public AssignCargoToRoute( Cargo cargo, Itinerary itinerary ) - { - cargoInspector = rolePlayer( CargoInspectorRole.class, cargo ); - - routeSpecification = cargo.routeSpecification().get(); - transportStatus = cargo.delivery().get().transportStatus().get(); - lastHandlingEvent = cargo.delivery().get().lastHandlingEvent().get(); - - this.itinerary = itinerary; - } - - public AssignCargoToRoute( String trackingIdString, Itinerary itinerary ) - { - this( loadEntity( Cargo.class, trackingIdString ), itinerary ); - } - - public void assign() - throws CannotCreateRouteSpecificationException, UnsatisfyingRouteException, InspectionException, RoutingException - { - // Pre-conditions - if( transportStatus.equals( CLAIMED ) ) - { - throw new RoutingException( "Can't re-route claimed cargo" ); - } - - cargoInspector.assignCargoToRoute(); - } - - @Mixins( CargoInspectorRole.Mixin.class ) - public interface CargoInspectorRole - { - void setContext( AssignCargoToRoute context ); - - void assignCargoToRoute() - throws CannotCreateRouteSpecificationException, UnsatisfyingRouteException, InspectionException; - - class Mixin - extends RoleMixin<AssignCargoToRoute> - implements CargoInspectorRole - { - @This - Cargo cargo; - - RouteSpecification newRouteSpec; - NextHandlingEvent nextHandlingEvent; - Delivery newDelivery; - - public void assignCargoToRoute() - throws CannotCreateRouteSpecificationException, UnsatisfyingRouteException, InspectionException - { - // Step 1 - Derive updated route specification - - newRouteSpec = new DeriveUpdatedRouteSpecification( cargo ).getRouteSpec(); - - // Step 2 - Verify that route satisfies route specification - - if( !newRouteSpec.isSatisfiedBy( c.itinerary ) ) - { - throw new UnsatisfyingRouteException( newRouteSpec, c.itinerary ); - } - - // Step 3 - Assign new route specification to cargo - - cargo.routeSpecification().set( newRouteSpec ); - - // Step 4 - Assign cargo to route - - cargo.itinerary().set( c.itinerary ); - - // Step 5 - Determine next handling event - - ValueBuilder<NextHandlingEvent> nextHandlingEventBuilder = vbf.newValueBuilder( NextHandlingEvent.class ); - nextHandlingEvent = nextHandlingEventBuilder.prototype(); - - if( c.transportStatus.equals( NOT_RECEIVED ) ) - { - // Routed unhandled cargo is expected to be received in origin. - nextHandlingEvent.handlingEventType().set( RECEIVE ); - nextHandlingEvent.location().set( c.itinerary.firstLeg().loadLocation().get() ); - } - else if( c.transportStatus.equals( ONBOARD_CARRIER ) ) - { - // Re-routed cargo onboard carrier is expected to be unloaded in next port (regardless of new itinerary). - Voyage voyage = c.lastHandlingEvent.voyage().get(); - CarrierMovement carrierMovement = voyage.carrierMovementDepartingFrom( c.lastHandlingEvent - .location() - .get() ); - - // Estimate carrier arrival time - LocalDate estimatedArrivalDate = carrierMovement.arrivalDate().get(); - if( c.lastHandlingEvent.completionDate().get().isAfter( carrierMovement.departureDate().get() ) ) - { - LocalDate start = carrierMovement.departureDate().get(); - LocalDate end = carrierMovement.arrivalDate().get(); - Duration duration = Duration.between( start, end ); - estimatedArrivalDate = c.lastHandlingEvent.completionDate().get().plus(duration); - } - - nextHandlingEvent.handlingEventType().set( UNLOAD ); - nextHandlingEvent.location().set( carrierMovement.arrivalLocation().get() ); - nextHandlingEvent.date().set( estimatedArrivalDate ); - nextHandlingEvent.voyage().set( c.lastHandlingEvent.voyage().get() ); - } - else // IN_PORT - { - // Re-routed cargo in port is expected to be loaded onto first carrier of new itinerary. - nextHandlingEvent.handlingEventType().set( LOAD ); - nextHandlingEvent.location().set( c.itinerary.firstLeg().loadLocation().get() ); - nextHandlingEvent.date().set( c.itinerary.firstLeg().loadDate().get() ); - nextHandlingEvent.voyage().set( c.itinerary.firstLeg().voyage().get() ); - } - - // Step 6 - Update cargo delivery status - - ValueBuilder<Delivery> deliveryBuilder = vbf.newValueBuilder( Delivery.class ); - newDelivery = deliveryBuilder.prototype(); - newDelivery.timestamp().set( Instant.now() ); - newDelivery.lastHandlingEvent().set( c.lastHandlingEvent ); - newDelivery.transportStatus().set( c.transportStatus ); - newDelivery.isUnloadedAtDestination().set( false ); - newDelivery.routingStatus().set( ROUTED ); - newDelivery.isMisdirected().set( false ); - newDelivery.eta().set( c.itinerary.eta() ); - newDelivery.itineraryProgressIndex().set( 0 ); - newDelivery.nextHandlingEvent().set( nextHandlingEventBuilder.newInstance() ); - - cargo.delivery().set( deliveryBuilder.newInstance() ); - } - } - } -} \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/booking/routing/RegisterNewDestination.java ---------------------------------------------------------------------- diff --git a/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/booking/routing/RegisterNewDestination.java b/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/booking/routing/RegisterNewDestination.java deleted file mode 100644 index a84bbbb..0000000 --- a/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/booking/routing/RegisterNewDestination.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * - */ -package org.apache.zest.sample.dcicargo.sample_b.context.interaction.booking.routing; - -import org.apache.zest.api.injection.scope.This; -import org.apache.zest.api.mixin.Mixins; -import org.apache.zest.api.unitofwork.NoSuchEntityException; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.booking.exception.ChangeDestinationException; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.booking.specification.DeriveUpdatedRouteSpecification; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.InspectCargoDeliveryStatus; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.exception.InspectionException; -import org.apache.zest.sample.dcicargo.sample_b.data.factory.exception.CannotCreateRouteSpecificationException; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.cargo.Cargo; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.cargo.RouteSpecification; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.TransportStatus; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.location.Location; -import org.apache.zest.sample.dcicargo.sample_b.infrastructure.dci.Context; -import org.apache.zest.sample.dcicargo.sample_b.infrastructure.dci.RoleMixin; - -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.TransportStatus.CLAIMED; - -/** - * Register New Destination (subfunction use case) - * - * Booking system has asked Cargo Inspector to register a new destination for a cargo. - */ -public class RegisterNewDestination extends Context -{ - CargoInspectorRole cargoInspector; - - TransportStatus transportStatus; -// HandlingEvent lastHandlingEvent; - - public RegisterNewDestination( Cargo cargo ) - { - this.cargoInspector = rolePlayer( CargoInspectorRole.class, cargo ); - - transportStatus = cargo.delivery().get().transportStatus().get(); -// lastHandlingEvent = cargo.delivery().get().lastHandlingEvent().get(); - } - - public RegisterNewDestination( String trackingIdString ) - { - this( loadEntity( Cargo.class, trackingIdString ) ); - } - - public void to( String destinationUnLocodeString ) - throws Exception - { - // Pre-conditions - if( transportStatus.equals( CLAIMED ) ) - { - throw new ChangeDestinationException( "Can't change destination of claimed cargo." ); - } - - cargoInspector.registerNewDestination( destinationUnLocodeString ); - } - - @Mixins( CargoInspectorRole.Mixin.class ) - public interface CargoInspectorRole - { - void setContext( RegisterNewDestination context ); - - void registerNewDestination( String destination ) - throws Exception; - - class Mixin - extends RoleMixin<RegisterNewDestination> - implements CargoInspectorRole - { - @This - Cargo cargo; - - Location newDestination; - RouteSpecification newRouteSpec; - - public void registerNewDestination( String newDestinationString ) - throws ChangeDestinationException, CannotCreateRouteSpecificationException, InspectionException - { - // Step 1 - Verify new destination - - try - { - newDestination = uowf.currentUnitOfWork().get( Location.class, newDestinationString ); - } - catch( NoSuchEntityException e ) - { - throw new ChangeDestinationException( "Didn't recognize location '" + newDestinationString + "'" ); - } - if( newDestination.equals( cargo.routeSpecification().get().destination().get() ) ) - { - throw new ChangeDestinationException( "New destination is same as old destination." ); - } - - // Step 2 - Derive new route specification - - newRouteSpec = new DeriveUpdatedRouteSpecification( cargo, newDestination ).getRouteSpec(); - - // Step 3 - Assign new route specification to cargo - - cargo.routeSpecification().set( newRouteSpec ); - - // Step 4 - Update cargo delivery status - - new InspectCargoDeliveryStatus( cargo ).update(); - } - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/booking/specification/DeriveUpdatedRouteSpecification.java ---------------------------------------------------------------------- diff --git a/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/booking/specification/DeriveUpdatedRouteSpecification.java b/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/booking/specification/DeriveUpdatedRouteSpecification.java deleted file mode 100644 index f6a201c..0000000 --- a/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/booking/specification/DeriveUpdatedRouteSpecification.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * - */ -package org.apache.zest.sample.dcicargo.sample_b.context.interaction.booking.specification; - -import java.time.LocalDate; -import org.apache.zest.api.injection.scope.Service; -import org.apache.zest.api.injection.scope.This; -import org.apache.zest.api.mixin.Mixins; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.exception.UnexpectedCarrierException; -import org.apache.zest.sample.dcicargo.sample_b.data.factory.RouteSpecificationFactoryService; -import org.apache.zest.sample.dcicargo.sample_b.data.factory.exception.CannotCreateRouteSpecificationException; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.cargo.Cargo; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.cargo.RouteSpecification; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.TransportStatus; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.handling.HandlingEvent; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.location.Location; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.voyage.CarrierMovement; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.voyage.Voyage; -import org.apache.zest.sample.dcicargo.sample_b.infrastructure.dci.Context; -import org.apache.zest.sample.dcicargo.sample_b.infrastructure.dci.RoleMixin; - -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.TransportStatus.CLAIMED; -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.TransportStatus.NOT_RECEIVED; -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.TransportStatus.ONBOARD_CARRIER; - -/** - * Derive Updated Route Specification (subfunction use case) - * - * A Cargo Owner requests to change the route for a Cargo. - * - * If the request happens during transport we have to consider the current location of the cargo. - * If currently on board a carrier we use the arrival port as the new origin for a new route specification - * otherwise simply the lastKnownLocation. Original origin location of Cargo remains the same. - */ -public class DeriveUpdatedRouteSpecification extends Context -{ - private CargoInspectorRole cargoInspector; - - private RouteSpecification routeSpecification; - private TransportStatus transportStatus; - private HandlingEvent lastHandlingEvent; - private Location newDestination; - - public DeriveUpdatedRouteSpecification( Cargo cargo ) - { - this.cargoInspector = rolePlayer( CargoInspectorRole.class, cargo ); - - routeSpecification = cargo.routeSpecification().get(); - transportStatus = cargo.delivery().get().transportStatus().get(); - lastHandlingEvent = cargo.delivery().get().lastHandlingEvent().get(); - } - - public DeriveUpdatedRouteSpecification( String trackingIdString ) - { - this( loadEntity( Cargo.class, trackingIdString ) ); - } - - public DeriveUpdatedRouteSpecification( Cargo cargo, Location newDestination ) - { - this( cargo ); - this.newDestination = newDestination; - } - - public RouteSpecification getRouteSpec() - throws CannotCreateRouteSpecificationException, UnexpectedCarrierException - { - // Pre-conditions - if( transportStatus.equals( CLAIMED ) ) - { - throw new CannotCreateRouteSpecificationException( "Can't derive new route specification for a claimed cargo." ); - } - - return cargoInspector.getUpdatedRouteSpecification(); - } - - @Mixins( CargoInspectorRole.Mixin.class ) - public interface CargoInspectorRole - { - void setContext( DeriveUpdatedRouteSpecification context ); - - RouteSpecification getUpdatedRouteSpecification() - throws CannotCreateRouteSpecificationException, UnexpectedCarrierException; - - class Mixin - extends RoleMixin<DeriveUpdatedRouteSpecification> - implements CargoInspectorRole - { - @This - Cargo cargo; - - @Service - RouteSpecificationFactoryService routeSpecFactory; - - Location newOrigin; - Location newDestination; - LocalDate newEarliestDeparture; - LocalDate newArrivalDeadline; - - public RouteSpecification getUpdatedRouteSpecification() - throws CannotCreateRouteSpecificationException, UnexpectedCarrierException - { - // Step 1 - Collect destination and deadline - - newDestination = c.newDestination == null ? c.routeSpecification.destination().get() : c.newDestination; - newArrivalDeadline = c.routeSpecification.arrivalDeadline().get(); - - // Step 2 - Derive origin and earliest departure date - - if( c.transportStatus.equals( NOT_RECEIVED ) ) - { - newOrigin = cargo.origin().get(); - newEarliestDeparture = c.routeSpecification.earliestDeparture().get(); - } - else if( c.transportStatus.equals( ONBOARD_CARRIER ) ) - { - Voyage voyage = c.lastHandlingEvent.voyage().get(); - Location departureLocation = c.lastHandlingEvent.location().get(); - CarrierMovement carrierMovement = voyage.carrierMovementDepartingFrom( departureLocation ); - if( carrierMovement == null ) - { - throw new UnexpectedCarrierException( c.lastHandlingEvent ); - } - - newOrigin = carrierMovement.arrivalLocation().get(); - newEarliestDeparture = carrierMovement.arrivalDate().get(); - } - else - { - newOrigin = c.lastHandlingEvent.location().get(); - newEarliestDeparture = c.lastHandlingEvent.completionDate().get(); - } - - // Step 3 - Build and return new route specification - - return routeSpecFactory.build( newOrigin, newDestination, newEarliestDeparture, newArrivalDeadline ); - } - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/ProcessHandlingEvent.java ---------------------------------------------------------------------- diff --git a/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/ProcessHandlingEvent.java b/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/ProcessHandlingEvent.java deleted file mode 100644 index 514c231..0000000 --- a/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/ProcessHandlingEvent.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * - */ -package org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling; - -import org.apache.zest.api.common.Optional; -import org.apache.zest.api.composite.TransientComposite; -import org.apache.zest.api.injection.scope.Service; -import org.apache.zest.api.mixin.Mixins; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.InspectCargoDeliveryStatus; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.exception.CargoArrivedException; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.exception.InspectionException; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.exception.InspectionFailedException; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.parsing.ParseHandlingEventData; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.parsing.dto.ParsedHandlingEventData; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.parsing.exception.InvalidHandlingEventDataException; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.registration.RegisterHandlingEvent; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.registration.exception.CannotRegisterHandlingEventException; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.handling.HandlingEvent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Process Handling Event (subfunction use case) - * - * This is the main subfunction use case for processing incoming handling event registration attempts - * from incident logging applications. - * - * The main responsibility here is to delegate the event processing to (sub)subfunction use cases - * and to notify relevant parties when certain conditions are met (exceptions thrown). Notifi- - * cations to the cargo owner are simply presented as red-color key words like "Misrouted" in - * the booking application UI. - * - * A "Handling Manager" in this use case delegates to to following Roles in Contexts - * (Subfunction Use Cases): - * - * 1. Data Parser in {@link ParseHandlingEventData} - * 2. Event Registrar in {@link RegisterHandlingEvent} - * 3. Delivery Inspector in {@link org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.InspectCargoDeliveryStatus} - * - * For now we simply (synchronously) invoke each subfunction use case with a method call. But - * we could also implement this asynchronously with JMS or other similar solutions and have - * message consumers initiate the subfunction use cases instead (as in JmsApplicationEventsImpl - * in the DDD sample). - */ -@Mixins( ProcessHandlingEvent.SynchronousProcessingStub.class ) -public interface ProcessHandlingEvent - extends TransientComposite -{ - - void parse( String completion, String trackingId, String eventType, String unLocode, @Optional String voyage ) - throws ProcessHandlingEventException; - - void register( ParsedHandlingEventData parsedHandlingEventData ) - throws ProcessHandlingEventException; - - void inspect( HandlingEvent handlingEvent ); - - abstract class SynchronousProcessingStub - implements ProcessHandlingEvent - { - Logger logger = LoggerFactory.getLogger( ProcessHandlingEvent.class ); - - @Service - ParseHandlingEventData parser; - - // Step 1 - Parse handling event data - - public void parse( String completion, String trackingId, String eventType, String unLocode, String voyage ) - throws ProcessHandlingEventException - { - logger.debug( "Received handling event registration attempt " ); - try - { - ParsedHandlingEventData parsedData = parser.parse( completion, trackingId, eventType, unLocode, voyage ); - logger.debug( "Parsed handling event data" ); - - register( parsedData ); - } - catch( InvalidHandlingEventDataException e ) - { - logger.info( e.getMessage() ); // Notify handling authority... - throw new ProcessHandlingEventException( e.getMessage() ); - } - } - - // Step 2 - Register handling event - - public void register( ParsedHandlingEventData parsedHandlingEventData ) - throws ProcessHandlingEventException - { - try - { - HandlingEvent handlingEvent = new RegisterHandlingEvent( parsedHandlingEventData ).getEvent(); - logger.debug( "Registered handling event" ); - - inspect( handlingEvent ); - } - catch( CannotRegisterHandlingEventException e ) - { - logger.info( e.getMessage() ); // Notify handling authority... - throw new ProcessHandlingEventException( e.getMessage() ); - } - } - - // Step 3 - Update cargo delivery status - - public void inspect( HandlingEvent handlingEvent ) - { - try - { - new InspectCargoDeliveryStatus( handlingEvent ).update(); - logger.info( "Inspected handled cargo '" + handlingEvent.trackingId().get().id().get() + "'." ); - } - catch( InspectionFailedException e ) - { - logger.error( e.getMessage() ); // Unexpected error - } - catch( CargoArrivedException e ) - { - logger.info( e.getMessage() ); // Request Cargo Owner to claim cargo at destination... - } - catch( InspectionException e ) - { - logger.info( e.getMessage() ); // Request Cargo Owner to re-route cargo... - } - } - } -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/ProcessHandlingEventException.java ---------------------------------------------------------------------- diff --git a/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/ProcessHandlingEventException.java b/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/ProcessHandlingEventException.java deleted file mode 100644 index 8f17573..0000000 --- a/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/ProcessHandlingEventException.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * - */ -package org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling; - -public class ProcessHandlingEventException extends Exception -{ - public ProcessHandlingEventException( String s ) - { - super( s ); - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/inspection/InspectCargoDeliveryStatus.java ---------------------------------------------------------------------- diff --git a/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/inspection/InspectCargoDeliveryStatus.java b/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/inspection/InspectCargoDeliveryStatus.java deleted file mode 100644 index 6a00563..0000000 --- a/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/inspection/InspectCargoDeliveryStatus.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * - */ -package org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection; - -import org.apache.zest.api.injection.scope.This; -import org.apache.zest.api.mixin.Mixins; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.event.InspectArrivedCargo; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.event.InspectCargoInCustoms; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.event.InspectClaimedCargo; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.event.InspectLoadedCargo; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.event.InspectReceivedCargo; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.event.InspectUnhandledCargo; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.event.InspectUnloadedCargo; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.exception.InspectionException; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.cargo.Cargo; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.handling.HandlingEvent; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.handling.HandlingEventType; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.location.Location; -import org.apache.zest.sample.dcicargo.sample_b.infrastructure.dci.Context; -import org.apache.zest.sample.dcicargo.sample_b.infrastructure.dci.RoleMixin; - -/** - * Inspect Cargo Delivery Status (subfunction use case) - * - * Third and last step in the ProcessHandlingEvent use case. - * - * Updates our knowledge about a cargo delivery. All we know about the delivery is saved in - * a Delivery value object that is replaced each time it's updated. - * - * Cargo is playing the Role of a Delivery Inspector that inspects a specific handling event - * in order to update the Delivery status for the cargo. - * - * If the Delivery Inspector realizes that the cargo is not on track, proper notifications are - * sent out so that the cargo owner can re-route the cargo or the system take some action. - * - * Handling cargo in customs is a completely different process and context than loading it onto - * a ship, so each handling event has its own use case and thus its own Context. Each of those - * (sub-)subfunction use cases/Contexts reflects our understanding of a real world process and - * can be easily reviewed, maintained, specialized, tested etc. It's now easy to understand - * what our program does and what we can expect from it - basically in one place in the code. - */ -public class InspectCargoDeliveryStatus extends Context -{ - DeliveryInspectorRole deliveryInspector; - - Location destination; - HandlingEvent handlingEvent; - Location handlingLocation; - - public InspectCargoDeliveryStatus( HandlingEvent handlingEvent ) - { - this.handlingEvent = handlingEvent; - - Cargo cargo = loadEntity( Cargo.class, handlingEvent.trackingId().get().id().get() ); - deliveryInspector = rolePlayer( DeliveryInspectorRole.class, cargo ); - - handlingLocation = handlingEvent.location().get(); - destination = cargo.routeSpecification().get().destination().get(); - } - - public InspectCargoDeliveryStatus( Cargo cargo ) - { - deliveryInspector = rolePlayer( DeliveryInspectorRole.class, cargo ); - destination = cargo.routeSpecification().get().destination().get(); - - handlingEvent = cargo.delivery().get().lastHandlingEvent().get(); - if( handlingEvent != null ) - { - handlingLocation = handlingEvent.location().get(); - } - } - - public void update() - throws InspectionException - { - deliveryInspector.delegateInspection(); - } - - @Mixins( DeliveryInspectorRole.Mixin.class ) - public interface DeliveryInspectorRole - { - void setContext( InspectCargoDeliveryStatus context ); - - void delegateInspection() - throws InspectionException; - - class Mixin - extends RoleMixin<InspectCargoDeliveryStatus> - implements DeliveryInspectorRole - { - @This - Cargo cargo; - - public void delegateInspection() - throws InspectionException - { - - // Step 1 - Determine handling event type - - if( c.handlingEvent == null ) - { - new InspectUnhandledCargo( cargo ).inspect(); - return; - } - HandlingEventType handlingEventType = c.handlingEvent.handlingEventType().get(); - - // Step 2 - Delegate inspection - - switch( handlingEventType ) - { - case RECEIVE: - new InspectReceivedCargo( cargo, c.handlingEvent ).inspect(); - break; - - case LOAD: - new InspectLoadedCargo( cargo, c.handlingEvent ).inspect(); - break; - - case UNLOAD: - if( c.handlingLocation.equals( c.destination ) ) - { - new InspectArrivedCargo( cargo, c.handlingEvent ).inspect(); - } - else - { - new InspectUnloadedCargo( cargo, c.handlingEvent ).inspect(); - } - break; - - case CUSTOMS: - new InspectCargoInCustoms( cargo, c.handlingEvent ).inspect(); - break; - - case CLAIM: - new InspectClaimedCargo( cargo, c.handlingEvent ).inspect(); - break; - - default: - // No other handling event types - } - } - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/inspection/event/InspectArrivedCargo.java ---------------------------------------------------------------------- diff --git a/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/inspection/event/InspectArrivedCargo.java b/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/inspection/event/InspectArrivedCargo.java deleted file mode 100644 index 699ba57..0000000 --- a/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/inspection/event/InspectArrivedCargo.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * - */ -package org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.event; - -import java.time.Instant; -import org.apache.zest.api.injection.scope.This; -import org.apache.zest.api.mixin.Mixins; -import org.apache.zest.api.value.ValueBuilder; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.exception.CargoArrivedException; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.exception.InspectionException; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.exception.InspectionFailedException; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.cargo.Cargo; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.cargo.RouteSpecification; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.Delivery; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.NextHandlingEvent; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.handling.HandlingEvent; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.itinerary.Itinerary; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.location.Location; -import org.apache.zest.sample.dcicargo.sample_b.infrastructure.dci.Context; -import org.apache.zest.sample.dcicargo.sample_b.infrastructure.dci.RoleMixin; - -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.RoutingStatus.MISROUTED; -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.RoutingStatus.NOT_ROUTED; -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.RoutingStatus.ROUTED; -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.TransportStatus.IN_PORT; -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.handling.HandlingEventType.CLAIM; -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.handling.HandlingEventType.UNLOAD; - -/** - * Inspect Arrived Cargo (subfunction use case) - * - * This is one the variations of the {@link org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.InspectCargoDeliveryStatus} use case. - */ -public class InspectArrivedCargo extends Context -{ - private DeliveryInspectorRole deliveryInspector; - - private HandlingEvent arrivalEvent; - private Location arrivalLocation; - - private RouteSpecification routeSpecification; - private Location destination; - - private Itinerary itinerary; - private Integer itineraryProgressIndex; - - public InspectArrivedCargo( Cargo cargo, HandlingEvent handlingEvent ) - { - deliveryInspector = rolePlayer( DeliveryInspectorRole.class, cargo ); - - arrivalEvent = handlingEvent; - arrivalLocation = arrivalEvent.location().get(); - - routeSpecification = cargo.routeSpecification().get(); - destination = routeSpecification.destination().get(); - itinerary = cargo.itinerary().get(); - - // Before handling - itineraryProgressIndex = cargo.delivery().get().itineraryProgressIndex().get(); - } - - public void inspect() - throws InspectionException - { - // Pre-conditions - if( arrivalEvent == null || - !arrivalEvent.handlingEventType().get().equals( UNLOAD ) || - !arrivalLocation.equals( destination ) ) - { - throw new InspectionFailedException( "Can only inspect arrived cargo." ); - } - - deliveryInspector.inspectArrivedCargo(); - } - - @Mixins( DeliveryInspectorRole.Mixin.class ) - public interface DeliveryInspectorRole - { - void setContext( InspectArrivedCargo context ); - - void inspectArrivedCargo() - throws InspectionException; - - class Mixin - extends RoleMixin<InspectArrivedCargo> - implements DeliveryInspectorRole - { - @This - Cargo cargo; - - Delivery newDelivery; - - public void inspectArrivedCargo() - throws InspectionException - { - // Step 1 - Collect known delivery data - - ValueBuilder<Delivery> newDeliveryBuilder = vbf.newValueBuilder( Delivery.class ); - newDelivery = newDeliveryBuilder.prototype(); - newDelivery.timestamp().set( Instant.now() ); - newDelivery.lastHandlingEvent().set( c.arrivalEvent ); - newDelivery.transportStatus().set( IN_PORT ); - - // Always on track if arrived at final destination - newDelivery.isUnloadedAtDestination().set( true ); - newDelivery.isMisdirected().set( false ); - - // Step 2 - Determine that cargo is routed (for internal reference) - - if( c.itinerary == null ) - { - newDelivery.routingStatus().set( NOT_ROUTED ); - newDelivery.eta().set( null ); - newDelivery.itineraryProgressIndex().set( 0 ); - } - else if( !c.routeSpecification.isSatisfiedBy( c.itinerary ) ) - { - newDelivery.routingStatus().set( MISROUTED ); - newDelivery.eta().set( null ); - newDelivery.itineraryProgressIndex().set( 0 ); - } - else - { - newDelivery.routingStatus().set( ROUTED ); - newDelivery.eta().set( c.itinerary.eta() ); - newDelivery.itineraryProgressIndex().set( c.itineraryProgressIndex ); - } - - // Step 3 - Set next expected handling event to claim - - ValueBuilder<NextHandlingEvent> nextHandlingEvent = vbf.newValueBuilder( NextHandlingEvent.class ); - nextHandlingEvent.prototype().handlingEventType().set( CLAIM ); - nextHandlingEvent.prototype().location().set( c.arrivalLocation ); - nextHandlingEvent.prototype().date().set( c.arrivalEvent.completionDate().get() ); - nextHandlingEvent.prototype().voyage().set( null ); - newDelivery.nextHandlingEvent().set( nextHandlingEvent.newInstance() ); - - // Step 4 - Save cargo delivery snapshot - - cargo.delivery().set( newDeliveryBuilder.newInstance() ); - - // Step 5 - Notify cargo owner of arrival at final destination - - // (Mockup for notification to cargo owner) - throw new CargoArrivedException( c.arrivalEvent ); - } - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/inspection/event/InspectCargoInCustoms.java ---------------------------------------------------------------------- diff --git a/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/inspection/event/InspectCargoInCustoms.java b/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/inspection/event/InspectCargoInCustoms.java deleted file mode 100644 index 421e634..0000000 --- a/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/inspection/event/InspectCargoInCustoms.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * - */ -package org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.event; - -import java.time.Instant; -import org.apache.zest.api.injection.scope.This; -import org.apache.zest.api.mixin.Mixins; -import org.apache.zest.api.value.ValueBuilder; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.exception.InspectionException; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.exception.InspectionFailedException; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.cargo.Cargo; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.cargo.RouteSpecification; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.Delivery; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.RoutingStatus; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.TransportStatus; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.handling.HandlingEvent; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.itinerary.Itinerary; -import org.apache.zest.sample.dcicargo.sample_b.infrastructure.dci.Context; -import org.apache.zest.sample.dcicargo.sample_b.infrastructure.dci.RoleMixin; - -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.RoutingStatus.NOT_ROUTED; -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.TransportStatus.IN_PORT; -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.TransportStatus.ONBOARD_CARRIER; -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.handling.HandlingEventType.CUSTOMS; - -/** - * Inspect Cargo In Customs (subfunction use case) - * - * This is one the variations of the {@link org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.InspectCargoDeliveryStatus} use case. - * - * Can the cargo get handled by customs only in the current port location?! Nothing now prevents - * an unexpected cargo in customs in some random location. A domain expert is needed to explain - * how this goes. - * - * For now the location doesn't affect the misdirection status, and we presume (hope) that the - * cargo will only get handled by customs in the port it's currently in. Should we safeguard - * against unexpected in-customs-locations? - */ -public class InspectCargoInCustoms extends Context -{ - private DeliveryInspectorRole deliveryInspector; - - private HandlingEvent customsEvent; - - private RouteSpecification routeSpecification; - private Itinerary itinerary; - private Integer itineraryProgressIndex; - private TransportStatus transportStatus; - - public InspectCargoInCustoms( Cargo cargo, HandlingEvent handlingEvent ) - { - deliveryInspector = rolePlayer( DeliveryInspectorRole.class, cargo ); - - customsEvent = handlingEvent; - - routeSpecification = cargo.routeSpecification().get(); - itinerary = cargo.itinerary().get(); - itineraryProgressIndex = cargo.delivery().get().itineraryProgressIndex().get(); - - // Transport status before customs handling - transportStatus = cargo.delivery().get().transportStatus().get(); - } - - public void inspect() - throws InspectionException - { - // Pre-conditions - if( customsEvent == null || !customsEvent.handlingEventType().get().equals( CUSTOMS ) ) - { - throw new InspectionFailedException( "Can only inspect cargo in customs." ); - } - - if( transportStatus.equals( ONBOARD_CARRIER ) ) - { - throw new InspectionFailedException( "Cannot handle cargo in customs on board a carrier." ); - } - - deliveryInspector.inspectCargoInCustoms(); - } - - @Mixins( DeliveryInspectorRole.Mixin.class ) - public interface DeliveryInspectorRole - { - void setContext( InspectCargoInCustoms context ); - - void inspectCargoInCustoms() - throws InspectionException; - - class Mixin - extends RoleMixin<InspectCargoInCustoms> - implements DeliveryInspectorRole - { - @This - Cargo cargo; - - Delivery newDelivery; - - public void inspectCargoInCustoms() - throws InspectionException - { - // Step 1 - Collect known delivery data - - ValueBuilder<Delivery> newDeliveryBuilder = vbf.newValueBuilder( Delivery.class ); - newDelivery = newDeliveryBuilder.prototype(); - newDelivery.timestamp().set( Instant.now() ); - newDelivery.lastHandlingEvent().set( c.customsEvent ); - newDelivery.transportStatus().set( IN_PORT ); - newDelivery.isUnloadedAtDestination().set( false ); - - // Customs handling location doesn't affect direction - newDelivery.isMisdirected().set( false ); - - // We can't predict the next handling event from the customs event - newDelivery.nextHandlingEvent().set( null ); - - // Step 2 - Verify cargo is routed - - if( c.itinerary == null ) - { - newDelivery.routingStatus().set( NOT_ROUTED ); - newDelivery.itineraryProgressIndex().set( 0 ); - newDelivery.eta().set( null ); - } - else if( !c.routeSpecification.isSatisfiedBy( c.itinerary ) ) - { - newDelivery.routingStatus().set( RoutingStatus.MISROUTED ); - newDelivery.itineraryProgressIndex().set( 0 ); - newDelivery.eta().set( null ); - } - else - { - newDelivery.routingStatus().set( RoutingStatus.ROUTED ); - newDelivery.itineraryProgressIndex().set( c.itineraryProgressIndex ); - newDelivery.eta().set( c.itinerary.eta() ); - } - - // Step 3 - Save cargo delivery snapshot - - cargo.delivery().set( newDeliveryBuilder.newInstance() ); - } - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/inspection/event/InspectClaimedCargo.java ---------------------------------------------------------------------- diff --git a/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/inspection/event/InspectClaimedCargo.java b/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/inspection/event/InspectClaimedCargo.java deleted file mode 100644 index 5f93b13..0000000 --- a/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/inspection/event/InspectClaimedCargo.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * - */ -package org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.event; - -import java.time.Instant; -import org.apache.zest.api.injection.scope.This; -import org.apache.zest.api.mixin.Mixins; -import org.apache.zest.api.value.ValueBuilder; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.exception.InspectionException; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.exception.InspectionFailedException; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.cargo.Cargo; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.cargo.RouteSpecification; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.Delivery; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.handling.HandlingEvent; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.itinerary.Itinerary; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.location.Location; -import org.apache.zest.sample.dcicargo.sample_b.infrastructure.dci.Context; -import org.apache.zest.sample.dcicargo.sample_b.infrastructure.dci.RoleMixin; - -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.RoutingStatus.MISROUTED; -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.RoutingStatus.NOT_ROUTED; -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.RoutingStatus.ROUTED; -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.TransportStatus.CLAIMED; -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.handling.HandlingEventType.CLAIM; - -/** - * Inspect Claimed Cargo (subfunction use case) - * - * This is one the variations of the {@link org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.InspectCargoDeliveryStatus} use case. - * - * NOTE: We don't throw any misrouted/misdirected exceptions even though the cargo might not have - * followed the original itinerary. The cargo has been delivered at destination and claimed by - * Cargo Owner, so we're happy no matter how it got there. - */ -public class InspectClaimedCargo extends Context -{ - private DeliveryInspectorRole deliveryInspector; - - private HandlingEvent claimEvent; - private Location claimLocation; - - private RouteSpecification routeSpecification; - private Itinerary itinerary; - private Integer itineraryProgressIndex; - - public InspectClaimedCargo( Cargo cargo, HandlingEvent handlingEvent ) - { - deliveryInspector = rolePlayer( DeliveryInspectorRole.class, cargo ); - - claimEvent = handlingEvent; - claimLocation = claimEvent.location().get(); - - routeSpecification = cargo.routeSpecification().get(); - itinerary = cargo.itinerary().get(); - - // Before handling - itineraryProgressIndex = cargo.delivery().get().itineraryProgressIndex().get(); - } - - public void inspect() - throws InspectionException - { - // Pre-conditions - if( claimEvent == null || !claimEvent.handlingEventType().get().equals( CLAIM ) ) - { - throw new InspectionFailedException( "Can only inspect claimed cargo." ); - } - - deliveryInspector.inspectClaimedCargo(); - } - - @Mixins( DeliveryInspectorRole.Mixin.class ) - public interface DeliveryInspectorRole - { - void setContext( InspectClaimedCargo context ); - - void inspectClaimedCargo() - throws InspectionException; - - class Mixin - extends RoleMixin<InspectClaimedCargo> - implements DeliveryInspectorRole - { - @This - Cargo cargo; - - Delivery newDelivery; - - public void inspectClaimedCargo() - throws InspectionException - { - // Step 1 - Collect known delivery data - - ValueBuilder<Delivery> newDeliveryBuilder = vbf.newValueBuilder( Delivery.class ); - newDelivery = newDeliveryBuilder.prototype(); - newDelivery.timestamp().set( Instant.now() ); - newDelivery.lastHandlingEvent().set( c.claimEvent ); - newDelivery.transportStatus().set( CLAIMED ); - newDelivery.isUnloadedAtDestination().set( false ); // Why not true if claimed in final destination? - - // Claim is end of delivery cycle - newDelivery.nextHandlingEvent().set( null ); - - // Step 2 - Determine that cargo was routed (for internal reference) - - if( c.itinerary == null ) - { - newDelivery.routingStatus().set( NOT_ROUTED ); - newDelivery.eta().set( null ); - newDelivery.itineraryProgressIndex().set( 0 ); - } - else if( !c.routeSpecification.isSatisfiedBy( c.itinerary ) ) - { - newDelivery.routingStatus().set( MISROUTED ); - newDelivery.eta().set( null ); - newDelivery.itineraryProgressIndex().set( 0 ); - } - else - { - newDelivery.routingStatus().set( ROUTED ); - newDelivery.eta().set( c.itinerary.eta() ); - newDelivery.itineraryProgressIndex().set( c.itineraryProgressIndex ); - } - - // Step 3 - Determine that cargo was on track according to itinerary (for internal reference) - - if( newDelivery.routingStatus().get().equals( ROUTED ) ) - { - newDelivery.isMisdirected() - .set( !c.claimLocation.equals( c.itinerary.lastLeg().unloadLocation().get() ) ); - } - else - { - newDelivery.isMisdirected().set( false ); - } - - // Step 4 - Save cargo delivery snapshot - - cargo.delivery().set( newDeliveryBuilder.newInstance() ); - } - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/inspection/event/InspectLoadedCargo.java ---------------------------------------------------------------------- diff --git a/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/inspection/event/InspectLoadedCargo.java b/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/inspection/event/InspectLoadedCargo.java deleted file mode 100644 index 090066c..0000000 --- a/samples/dci-cargo/dcisample_b/src/main/java/org/apache/zest/sample/dcicargo/sample_b/context/interaction/handling/inspection/event/InspectLoadedCargo.java +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * - */ -package org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.event; - -import java.time.Duration; -import java.time.Instant; -import java.time.LocalDate; -import java.time.Period; -import java.util.Random; -import org.apache.zest.api.injection.scope.This; -import org.apache.zest.api.mixin.Mixins; -import org.apache.zest.api.value.ValueBuilder; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.exception.CargoHijackedException; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.exception.CargoMisdirectedException; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.exception.CargoMisroutedException; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.exception.CargoNotRoutedException; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.exception.InspectionException; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.exception.InspectionFailedException; -import org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.exception.UnexpectedCarrierException; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.cargo.Cargo; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.cargo.RouteSpecification; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.Delivery; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.NextHandlingEvent; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.RoutingStatus; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.handling.HandlingEvent; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.itinerary.Itinerary; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.itinerary.Leg; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.location.Location; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.voyage.CarrierMovement; -import org.apache.zest.sample.dcicargo.sample_b.data.structure.voyage.Voyage; -import org.apache.zest.sample.dcicargo.sample_b.infrastructure.dci.Context; -import org.apache.zest.sample.dcicargo.sample_b.infrastructure.dci.RoleMixin; - -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.RoutingStatus.MISROUTED; -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.RoutingStatus.NOT_ROUTED; -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.TransportStatus.ONBOARD_CARRIER; -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.delivery.TransportStatus.UNKNOWN; -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.handling.HandlingEventType.LOAD; -import static org.apache.zest.sample.dcicargo.sample_b.data.structure.handling.HandlingEventType.UNLOAD; - -/** - * Inspect Loaded Cargo (subfunction use case) - * - * This is one the variations of the - * {@link org.apache.zest.sample.dcicargo.sample_b.context.interaction.handling.inspection.InspectCargoDeliveryStatus} use - * case. - * - * When the cargo is loaded onto some unexpected carrier we need to find out where that carrier - * is going so that we can make a new route specification starting from that location. The Cargo Owner - * is then requested to re-route the cargo in order to get the cargo back on track. - */ -public class InspectLoadedCargo extends Context -{ - private DeliveryInspectorRole deliveryInspector; - - private HandlingEvent loadEvent; - private Location loadLocation; - private Voyage voyage; - - private RouteSpecification routeSpecification; - private Itinerary itinerary; - private Integer itineraryProgressIndex; - private RoutingStatus oldRoutingStatus; - - public InspectLoadedCargo( Cargo cargo, HandlingEvent handlingEvent ) - { - deliveryInspector = rolePlayer( DeliveryInspectorRole.class, cargo ); - - loadEvent = handlingEvent; - loadLocation = loadEvent.location().get(); - voyage = loadEvent.voyage().get(); - - routeSpecification = cargo.routeSpecification().get(); - itinerary = cargo.itinerary().get(); - - // Before handling - itineraryProgressIndex = cargo.delivery().get().itineraryProgressIndex().get(); - oldRoutingStatus = cargo.delivery().get().routingStatus().get(); - } - - public void inspect() - throws InspectionException - { - // Pre-conditions - if( loadEvent == null || !loadEvent.handlingEventType().get().equals( LOAD ) ) - { - throw new InspectionFailedException( "Can only inspect loaded cargo." ); - } - - deliveryInspector.inspectLoadedCargo(); - } - - @Mixins( DeliveryInspectorRole.Mixin.class ) - public interface DeliveryInspectorRole - { - void setContext( InspectLoadedCargo context ); - - void inspectLoadedCargo() - throws InspectionException; - - abstract class Mixin extends RoleMixin<InspectLoadedCargo> implements DeliveryInspectorRole - { - @This - Cargo cargo; - - Delivery newDelivery; - - public void inspectLoadedCargo() - throws InspectionException - { - // Step 1 - Collect known delivery data - - ValueBuilder<Delivery> newDeliveryBuilder = vbf.newValueBuilder( Delivery.class ); - newDelivery = newDeliveryBuilder.prototype(); - newDelivery.timestamp().set( Instant.now() ); - newDelivery.lastHandlingEvent().set( c.loadEvent ); - newDelivery.transportStatus().set( ONBOARD_CARRIER ); - newDelivery.isUnloadedAtDestination().set( false ); - - // Step 2 - Determine next unload from carrier - - CarrierMovement carrierMovement = c.voyage.carrierMovementDepartingFrom( c.loadLocation ); - if( carrierMovement == null ) - { - // Unexpected carrier movement - newDelivery.routingStatus().set( c.oldRoutingStatus ); - newDelivery.eta().set( null ); - newDelivery.itineraryProgressIndex().set( 0 ); - newDelivery.isMisdirected().set( true ); - cargo.delivery().set( newDeliveryBuilder.newInstance() ); - throw new UnexpectedCarrierException( c.loadEvent ); - } - - // Estimate carrier arrival time - LocalDate estimatedArrivalDate = carrierMovement.arrivalDate().get(); - if( c.loadEvent.completionDate().get().isAfter( carrierMovement.departureDate().get() ) ) - { - LocalDate start = carrierMovement.departureDate().get(); - LocalDate end = carrierMovement.arrivalDate().get(); - Period duration = Period.between( start, end ); - estimatedArrivalDate = c.loadEvent.completionDate().get().plus( duration ); - // ... We could notify cargo owner if we already now know that we will miss the next ship - } - - ValueBuilder<NextHandlingEvent> nextHandlingEvent = vbf.newValueBuilder( NextHandlingEvent.class ); - nextHandlingEvent.prototype().handlingEventType().set( UNLOAD ); - nextHandlingEvent.prototype().location().set( carrierMovement.arrivalLocation().get() ); - nextHandlingEvent.prototype().date().set( estimatedArrivalDate ); - nextHandlingEvent.prototype().voyage().set( c.voyage ); - newDelivery.nextHandlingEvent().set( nextHandlingEvent.newInstance() ); - - // Step 3 - Verify cargo is routed - - if( c.itinerary == null ) - { - newDelivery.routingStatus().set( NOT_ROUTED ); - newDelivery.eta().set( null ); - newDelivery.itineraryProgressIndex().set( 0 ); - cargo.delivery().set( newDeliveryBuilder.newInstance() ); - throw new CargoNotRoutedException( c.loadEvent ); - } - if( !c.routeSpecification.isSatisfiedBy( c.itinerary ) ) - { - newDelivery.routingStatus().set( MISROUTED ); - newDelivery.eta().set( null ); - newDelivery.itineraryProgressIndex().set( 0 ); - cargo.delivery().set( newDeliveryBuilder.newInstance() ); - throw new CargoMisroutedException( c.loadEvent, c.routeSpecification, c.itinerary ); - } - newDelivery.routingStatus().set( RoutingStatus.ROUTED ); - newDelivery.eta().set( c.itinerary.eta() ); - newDelivery.itineraryProgressIndex().set( c.itineraryProgressIndex ); - - // Step 4 - Verify cargo is on track - - Leg plannedCarrierMovement = c.itinerary.leg( c.itineraryProgressIndex ); - - // Unexpected internal state - if( plannedCarrierMovement == null ) - { - // We should always know the current itinerary leg - throw new InspectionFailedException( "Itinerary progress index '" + c.itineraryProgressIndex + "' is invalid!" ); - } - - // Unexpected load location - Cargo can't travel in time! - // Either previous or current location is wrong - only investigation can clarify... - if( !plannedCarrierMovement.loadLocation().get().equals( c.loadLocation ) ) - { - newDelivery.isMisdirected().set( true ); - newDelivery.nextHandlingEvent().set( null ); - cargo.delivery().set( newDeliveryBuilder.newInstance() ); - throw new CargoMisdirectedException( c.loadEvent, "Itinerary expected load in " - + plannedCarrierMovement.loadLocation() - .get() - .getString() ); - } - - // Unexpected carrier - if( !plannedCarrierMovement.voyage().get().equals( c.voyage ) ) - { - newDelivery.isMisdirected().set( true ); - cargo.delivery().set( newDeliveryBuilder.newInstance() ); - - // ...Expected arrival location - should we accept this? - if( plannedCarrierMovement.unloadLocation() - .get() - .equals( carrierMovement.arrivalLocation().get() ) ) - { - throw new CargoMisdirectedException( c.loadEvent, c.itinerary, "Cargo is heading to expected arrival location " - + plannedCarrierMovement.unloadLocation() - .get() + " but on unexpected voyage " - + c.voyage - .toString() + ". Notify shipper to unload unexpected cargo in next port." ); - } - - throw new CargoMisdirectedException( c.loadEvent, c.itinerary, "Itinerary expected load onto voyage " - + plannedCarrierMovement.voyage() - .get() ); - } - - // Unexpected carrier destination - if( !plannedCarrierMovement.unloadLocation().get().equals( carrierMovement.arrivalLocation().get() ) ) - { - newDelivery.isMisdirected().set( true ); - cargo.delivery().set( newDeliveryBuilder.newInstance() ); - throw new CargoMisdirectedException( c.loadEvent, "Itinerary expects voyage " + c.voyage.toString() - + " to arrive in " + plannedCarrierMovement.unloadLocation() - .get() + " but carrier is now going to " - + carrierMovement.arrivalLocation().get() ); - } - - // True exception - if( ( c.loadLocation.getCode().equals( "SOMGQ" ) && new Random().nextInt( 100 ) < 20 ) || - ( carrierMovement.arrivalLocation() - .get() - .getCode() - .equals( "SOMGQ" ) && new Random().nextInt( 100 ) < 15 ) ) - { - newDelivery.transportStatus().set( UNKNOWN ); - newDelivery.isMisdirected().set( false ); - cargo.delivery().set( newDeliveryBuilder.newInstance() ); - throw new CargoHijackedException( c.loadEvent ); - } - - // Cargo is on track - newDelivery.isMisdirected().set( false ); - - // Step 5 - Save cargo delivery snapshot - - cargo.delivery().set( newDeliveryBuilder.newInstance() ); - } - } - } -} \ No newline at end of file
