Implement domain command

Command base

  • For each root entity there will be an abstract class Command Base generated in the SDK.

  • The Command Base provide access to the repository, the entity builder, the event builder and the event producer.

  • The Command Base contains abstract methods, one method for each modelled command.

  • These Commands method needs to be implemented in the generated implementation file for the Root Entity Commands.

Factory and instance commands

  • Factory commands will return Root Entity as a return type, Instance commands always return void.

  • Factory commands take an Input Entity as the only parameter, if they have been modelled with one.

  • Instance commands take an instance of Root Entity as the first parameter named instance and an Input Entity if they have been modelled with one.

  • Instance commands operate against the root entity instance that is passed to it.

Business errors

  • If a command is modelled with business errors, it will be added as method throws declaration.

Events

  • If a root entity command is modelled with business events, for each event there will be an inherited method in the Command Base class that takes the event as an input and publishes it.

  • It is also possible to publish events directly using EventProducerService.

Implementation Example

Example of root entity command implementation file.

Root Entity Card has a factory command createCreditCard and an instance command activateCreditCard.

    //... imports

	@Service
	public class CardCommand extends CardCommandBase {

		private static Logger log = LoggerFactory.getLogger(CardCommand.class);
		
		public CardCommand(DomainEntityBuilder entityBuilder, 
						   DomainEventBuilder eventBuilder, 
						   EventProducerService eventProducer,
						   Repository repo) {
			super(entityBuilder, eventBuilder, eventProducer, repo);
		}

		// Example of a factory command named createCreditCard that takes CreditCard as an input entity
		@Override
		public Card createCreditCard(CreditCard creditCard) throws CreditCardCreationError {

			log.info("CardCommands.createCreditCard()");
	
			// Use Domain Entity Builder from base class to create an instance of root entity
			Card cardRootEntity = this.entityBuilder.getCc().getCard().build();

			// Use card details data from the input entity
			cardRootEntity.setCardDetails(creditCard);
			cardRootEntity.setIsActive(false);

			// If an Exception occurred while saveing new card, catch and throw relevant business error
			try {
				cardRootEntity = this.repo.getCc().getCard().save(cardRootEntity);
			} catch(Exception e) {
			log.error("Could not create a new credit card", e);
			String errorMessage = String.format("Credit card creation failure, %s" , e.getMessag());
			throw new CreditCardCreationError(errorMessage);
			}
		
			log.info("Saved a new Credit Card Root Entity with Id {}", cardRootEntity.getId());

			// Create an event and set payload entity
			CreditCardCreated event = this.eventBuilder.getCc().getCreditCardCreated().build();
			event.setPayload(creditCard);

			// Pusblish event using base class inherited method
			this.publishCreditCardCreated(event);

			log.info("Published New Credit Card Event Successfully");
			
			return cardRootEntity;
		}

		// Example of an  instance named activateCreditCard that takes only the Card root entity.
		@Override
		public void activateCreditCard(Card instance) {

			log.info("CardCommands.activateCreditCard()");
	
			// Activate Card
			instance.setActive(true);

			// Update root entity 
			this.repo.getCc().getCard().save(instance);
			
			log.info("Activated Card with Id {}", instance.getId());
			
			return;
		}
Note: If you are using the aggregate persistence functionality, please ensure that your code is compliant with the recommended restrictions of the used database. Consult MongoDB documentation for further information. For example: Because of the limitations of database operations and drivers, MongoDB does not recommend the use of timestamps, that are not within the year range of 0 - 9999, see Date and DateTime documentation.