Passaggi da seguire dopo creazione o modifica entity v2

how to write essay on myself in english free essay writer how to write a cover letter nursing

Dopo la creazione di una entity sono necessari i seguenti passaggi:

  1. Aggiunta configurazione code nell’application.yml
  2. Creazione resource aggiuntive per la ripubblicazione di alcuni eventi
  3. Creazione delle entity aggregate
  4. Creazione scodatori per popolare gli aggregate
  5. Modifica del puntamento delle resource di lettura dalle entity alle aggregate

Inoltre va configurato nell’application.yml l’exchange nel quale scrivere

  cloud:
    stream:
      bindings:
      	...
        createUpdateBuyer-Output:
          destination: createUpdateBuyerExchange
          contentType: application/json
        deleteBuyer-Output:
          destination: deleteBuyerExchange
          contentType: application/json

3. Metodi aggiuntivi nei metodi resource per la ripubblicazione di alcuni eventi

Potrebbe essere necessaro ripubblicare gli eventi di createUpdate in modo che eventuali listner possano ri-aggiornare i propri valori, per far questo si prevede una risorsa REST per fare questo, accessibile solo da admin.

Nella resource della entity aggiungere il seguente metodo:

    @GetMapping("/buyers/publish")
    public ResponseEntity<String> publish(BuyerCriteria criteria, Pageable pageable) {
    	log.debug("REST request to republish by criteria: {} and page: {}", criteria, pageable);
    	
    	// Access Roule
    	UcpPermission.verifyPermission("c6e.admin");
    	
    	// Execution
		int republishedQuantity = buyerBusinessService.republishCreateUpdate(criteria, pageable);

        return new ResponseEntity<String>("" + republishedQuantity, HttpStatus.OK);
    }

4. Creazione delle entity aggregate

Le entity aggregate sono uno strumento pensato per vari fattori: velocizzare la lettura, ricerche approfondite, orientare le letture verso no-sql.

Per creare gli aggregate è necessario iniziare duplicando ogni entity esistente ma anteponendo il termine Aggregate al nome della entity, ed anteponendo agg_ al nome della tabella. ad esempio:

entity Buyer (a_buyer) { }

entity AggregateBuyer (agg_a_buyer) { }

Successivamente per ogni campo dell’entity va anteposto il nome dell’entity (facendo attenzione a rispettare sempre il formato camelBack) ad esempio:

entity Buyer (a_buyer) {
    eopooCode String required,
    confirmation Boolean required,
    statusNote String,
}

entity AggregateBuyer (agg_a_buyer) {
	buyerEopooCode String,
	buyerConfirmation Boolean,
	buyerStatusNote String,
}

Nell’aggregate va inoltre aggiunto un campo iniziale nel quale verrà inserito l’id dell’entity originale, che si chiamerà con nome entity ed in aggiunta ID come ad esempio: buyerID Integer required

Il campo dell’id dell’entity principale sarà l’unico ad essere required!

A questo punto vanno aggiunti tutti i campi delle entity parent sempre anteponendo al nome del campo il nome dell’entity di riferimento, come di seguito:

entity AggregateBuyer (agg_a_buyer) {
	buyerID Integer required,
	buyerEopooCode String,
	buyerConfirmation Boolean,
	buyerStatusNote String,
	
	sellerID Integer,
	sellerEopooCode String,
	sellerName String,
}

Una vota aggiunte le entity aggregate nel JDL princuipale nel branch entity_creation generare il codice come indicato nell’apposita guida.

Come ultimo passaggio di preparazione degli aggregate vanno creati i mapper, tra entity ed aggregate, queste classi mapper useranno MapStruct e dovranno essere create nel pacchetto aggregate.mapper come nel seguente esempio:

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

import com.eneasys.apigest.contexts_apps.commerce.service.dto.AggregateBuyerDTO;
import com.eneasys.apigest.contexts_apps.commerce.service.dto.BuyerDTO;

@Mapper(componentModel = "spring", uses = {})
public interface BuyerDTOMapper {
    @Mapping(source = "buyerID", target = "id")
    @Mapping(source = "buyerConfirmation", target = "confirmation")
    @Mapping(source = "buyerStatusNote", target = "statusNote")
    @Mapping(source = "buyerEopooCode", target = "eopooCode")
    @Mapping(source = "sellerID", target = "sellerId")
	    @Mapping(source = "sellerID", target = "seller.id")
	    @Mapping(source = "sellerName", target = "seller.name")
    	@Mapping(source = "sellerEopooCode", target = "seller.eopooCode")
    BuyerDTO toDto(AggregateBuyerDTO aggregateBuyerDTO);

    @Mapping(source = "id", target = "buyerID")
    @Mapping(source = "confirmation", target = "buyerConfirmation")
    @Mapping(source = "statusNote", target = "buyerStatusNote")
    @Mapping(source = "eopooCode", target = "buyerEopooCode")    
	@Mapping(source = "sellerId", target = "sellerID")
	    @Mapping(source = "seller.name", target = "sellerName")
		@Mapping(source = "seller.eopooCode", target = "sellerEopooCode")
    AggregateBuyerDTO toAggregate(BuyerDTO buyerDTO);
}

5. Creazione scodatori per popolare gli aggregate

Va inoltre configurato nel file application.yml a quali Exchange collegare i listner e come chiamare le code

  cloud:
    stream:
      bindings:
      	...
        createUpdateBuyer-createUpdateBuyerAggregate-Input:
          destination: createUpdateBuyerExchange
          group: createUpdateBuyerAggregateQueue
          contentType: application/json
        createUpdateSeller-createUpdateBuyerAggregate-Input:
          destination: createUpdateSellerExchange
          group: createUpdateBuyerAggregateQueue
          contentType: application/json
          
        deleteBuyer-deleteBuyerAggregate-Input:
          destination: deleteBuyerExchange
          group: deleteBuyerAggregateQueue
          contentType: application/json
        

La seconda classe da creare per la gestione dell’evento è la seguente:

Questa classe necessita di vari metodi nel layer di entity degli aggregate da implementare nel service come nel seguente esempio:

public interface AggregateBuyerService {
	...
      
      
    public Optional<AggregateBuyerDTO> findByBuyerId(Integer buyerId);
    
    public void updateBuyer(AggregateBuyerDTO aggregateBuyerDTO);
    
    public Optional<List<AggregateBuyerDTO>> findBySellerId(Integer sellerId);
    
    public void updateSeller(AggregateBuyerDTO aggregateBuyerDTO);
}
public class AggregateBuyerServiceImpl implements AggregateBuyerService {
  	...
      
      
    @Override
    @Transactional(readOnly = true)
	public Optional<AggregateBuyerDTO> findByBuyerId(Integer buyerId) {
        log.debug("Request to get all AggregateBuyers by buyer: {}", buyerId);
        return aggregateBuyerRepository.findByBuyerID(buyerId)
            .map(aggregateBuyerMapper::toDto);
	}

	@Override
	public void updateBuyer(AggregateBuyerDTO aggregateBuyerDTO) {
        log.debug("Request to updateBuyer in AggregateBuyer : {}", aggregateBuyerDTO);
        aggregateBuyerRepository.updateBuyer(aggregateBuyerDTO.getBuyerID(), 
        									 aggregateBuyerDTO.getBuyerEopooCode(), 
        									 aggregateBuyerDTO.getBuyerStatusNote(), 
        									 aggregateBuyerDTO.isBuyerConfirmation(),
        									 aggregateBuyerDTO.getSellerID(), 
        									 aggregateBuyerDTO.getSellerEopooCode(), 
        									 aggregateBuyerDTO.getSellerName());
	}

	@Override
    @Transactional(readOnly = true)
    public Optional<List<AggregateBuyerDTO>> findBySellerId(Integer sellerId) {
        log.debug("Request to get all AggregateBuyers by seller: {}", sellerId);
        return aggregateBuyerRepository.findBySellerID(sellerId)
            .map(aggregateBuyerMapper::toDto);
    }
   
    @Override
    public void updateSeller(AggregateBuyerDTO aggregateBuyerDTO) {
        log.debug("Request to updateSeller in AggregateBuyer: {}", aggregateBuyerDTO);
        aggregateBuyerRepository.updateSeller(aggregateBuyerDTO.getSellerID(), 
        									  aggregateBuyerDTO.getSellerEopooCode(), 
        									  aggregateBuyerDTO.getSellerName());
    }
}

A sua volta il layer di entity necessita modifiche nel layer di repository come di seguito:

public interface AggregateBuyerRepository extends JpaRepository<AggregateBuyer, Long>, JpaSpecificationExecutor<AggregateBuyer> {

	public Optional<AggregateBuyer> findByBuyerID(Integer buyerId);

	@Modifying
	@Query("update AggregateBuyer u "
			+ " set u.buyerEopooCode = :buyerEopooCode, "
			+ "		u.buyerStatusNote = :buyerStatusNote, "
			+ "		u.buyerConfirmation = :buyerConfirmation,"
			+ "		u.sellerID = :sellerID,"
			+ "		u.sellerEopooCode = :sellerEopooCode,"
			+ "		u.sellerName = :sellerName"
			+ " where u.buyerID = :buyerID")
	public void updateBuyer(@Param(value = "buyerID") Integer buyerID, 
							@Param(value = "buyerEopooCode") String buyerEopooCode, 
							@Param(value = "buyerStatusNote") String buyerStatusNote, 
							@Param(value = "buyerConfirmation") Boolean buyerConfirmation,
							@Param(value = "sellerID") Integer sellerID,
							@Param(value = "sellerEopooCode") String sellerEopooCode,
							@Param(value = "sellerName") String sellerName);
	
	public Optional<List<AggregateBuyer>> findBySellerID(Integer sellerId);
	
	@Modifying
	@Query("update AggregateBuyer u "
			+ "	set u.sellerEopooCode = :sellerEopooCode, "
			+ "		u.sellerName = :sellerName "
			+ " where u.sellerID = :sellerID")
	public void updateSeller(@Param(value = "sellerID") Integer sellerID, 
							 @Param(value = "sellerEopooCode") String sellerEopooCode, 
							 @Param(value = "sellerName") String sellerName);
}

Una volta fatto questo quando l’appicativo riceve un messaggio di createUpdate o di delete di un entità tale azione verrà eseguita anche sull’aggregate corrispondente.

6. Modifica del puntamento delle resource di lettura dalle entity alle aggregate

Quando i dati delle entity saranno anche inserite sulle ripettive aggregate si potrà far leggere le informazioni dall’aggregate in modo da velocizzare la lettura ed estendere le funzionalità di filtro a molti più campi.

Per poter fare questo bisognerà cambiare il puntamento nel layer di resource REST in modo da far leggere dagli aggregate e non dalle entity, lo si fa come di seguito in esempio:

public class BuyerResource {
  
	...
      
    @GetMapping("/buyers")
    public ResponseEntity<List<BuyerDTO>> getAllBuyers(AggregateBuyerCriteria criteria, Pageable pageable) {
    	log.debug("REST request to get Buyers by criteria: {}", criteria);
    	// Access Roule
    	UcpPermission.verifyPermission("c6e.admin");
    	// Execution
        Page<AggregateBuyerDTO> pageAggregateBuyerDTO = aggregateBuyerQueryService.findByCriteria(criteria, pageable);
        // Trasformation Roule
        Page<BuyerDTO> pageBuyerDTO = pageAggregateBuyerDTO.map(buyerDTOMapper::toDto);
        // Return
        HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), pageBuyerDTO);
        return ResponseEntity.ok().headers(headers).body(pageBuyerDTO.getContent());
    }
  
	...
      
    @GetMapping("/buyers/count")
    public ResponseEntity<Long> countBuyers(AggregateBuyerCriteria criteria) {
        log.debug("REST request to count Buyers by criteria: {}", criteria);
        // Access Roule
        UcpPermission.verifyPermission("c6e.admin");
        // Execution
        return ResponseEntity.ok().body(aggregateBuyerQueryService.countByCriteria(criteria));
    }

	...
  
    @GetMapping("/buyers/{id}")
    public ResponseEntity<BuyerDTO> getBuyer(@PathVariable Long id) {
        log.debug("REST request to get Buyer: {}", id);
        // Access Roule
        UcpPermission.verifyPermission("c6e.admin");
        // Execution
        Optional<BuyerDTO> optionalBuyerDTO = aggregateBuyerService.findByBuyerId(new Integer(id.intValue())).map(buyerDTOMapper::toDto);
        // Return
        return ResponseUtil.wrapOrNotFound(optionalBuyerDTO);
    }
	...
}