Professional Documents
Culture Documents
Exercice 1
1ère Solution : On considère ces deux web services SOAP :
OrderManagementService et CustomerManagementService.
On présente l'interface de ces services par deux classes (voir
figure). Ces deux services gèrent les clients et leurs commandes.
Un client est identifié par un id et a un nom et un prénom. Un
client possède des commandes. Une commande est identifiée
par un id et a une description, un montant et un statut.
1. Donner un WSDL pour le web service CustomerManagementServicve (uniquement
discription abstraite).
<wsdl:definitions
xmlns:wsdl=http://schemas.xmlsoap.org/wsdl/
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://www.tekup.de/country/ws/Customers"
targetNamespace="http://www.tekup.de/ws/Customers">
<wsdl:types>
<xs:schema xmlns:xs=http://www.w3.org/2001/XMLSchema
elementFormDefault="qualified"
targetNamespace="http://www.tekup.de/ws/Customers">
<xs:simpleType name="status">
<xs:restriction base="xs:string">
<xs:enumeration value="received"/>
<xs:enumeration value="in_progress"/>
<xs:enumeration value="approved"/>
<xs:enumeration value="complete"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="order">
<xs:sequence>
<xs:element name="id" type="xs:ID"/>
<xs:element name="description" type="xs:string"/>
<xs:element name="amount" type="xs:float"/>
<xs:element name="stat" type="tns:statut"/>
</xs:sequence>
</xs:complexType>
<xsd:complexTypename="orderArray" final="#all">
<xsd:sequence>
<xsd:elementname="item" type="tns:order" minOccurs="0"
maxOccurs="unbounded" nillable="true"/>
</xsd:sequence>
</xsd:complexType>
<xs:complexType name="customer">
<xs:sequence>
<xs:element name="id" type="xs:ID"/>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
<xs:element name="Orders" type= "tns:orderArray"/>
</xs:sequence>
</xs:complexType>
<xsd:complexTypename="customerArray" final="#all">
<xsd:sequence>
<xsd:element name="item" type="tns:customer" minOccurs="0"
maxOccurs="unbounded" nillable="true"/>
</xsd:sequence>
</xsd:complexType>
</xs:schema>
</wsdl:types>
<message name="getCustomersRequest"/>
<message name="getCustomersResponse">
<part name="value" type="tns:customerArray"/>
</message>
<message name="addCustomerRequest">
<part name="value1" type="xs:string"/>
<part name="value2" type="xs:string"/>
</message>
<message name="addCustomerResponse">
<part name="value" type="tns:customer"/>
</message>
<message name="getCustomerDetailsRequest">
<part name="value" type="xsd:ID"/>
</message>
<message name="getCustomerDetailsResponse">
<part name="value" type="tns:customer"/>
</message>
<message name="updateCustomerRequest">
<part name="value1" type="xs:ID"/>
<part name="value2" type="xs:string"/>
<part name="value3" type="xs:string"/>
</message>
<message name="updateCustomerResponse">
<part name="value" type="tns:customer"/>
</message>
<message name="deleteCustomerRequest">
<part name="value" type="xs:ID"/>
</message>
<message name="deleteCustomerResponse">
<part name="value" type="tns:customer"/>
</message>
<wsdl:portType name="CustomerService">
<wsdl:operation name="getCustomers">
<wsdl:input message="tns: getCustomersRequest"></wsdl:input>
<wsdl:output message="tns: getCustomersResponse"></wsdl:output>
</wsdl:operation>
<wsdl:operation name="addCustomer">
<wsdl:input message="tns:addCustomerRequest"></wsdl:input>
<wsdl:output message="tns:addCustomerResponse"></wsdl:output>
</wsdl:operation>
<wsdl:operation name="getCustomerDetails">
<wsdl:input message="tns:getCustomerDetailsRequest"></wsdl:input>
<wsdl:output message="tns:getCustomerDetailsResponse"></wsdl:output>
</wsdl:operation>
<wsdl:operation name="updateCustomer">
<wsdl:input message="tns:updateCustomerRequest"></wsdl:input>
<wsdl:output message="tns:updateCustomerResponse"></wsdl:output>
</wsdl:operation>
<wsdl:operation name="deleteCustomer">
<wsdl:input message="tns:deleteCustomerRequest"></wsdl:input>
<wsdl:output message="tns:deleteCustomerResponse"></wsdl:output>
</wsdl:operation>
</wsdl:portType>
2. Donner un message SOAP pour appeler l’opération getCustomerDetails().
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:tns=" http://www.tekup.de/ws/Customers">
<soapenv:Header/>
<soapenv:Body>
<tns:getCustomerDetailsRequest >
<value>2</value>
</tns:getCustomerDetailsRequest>
</soapenv:Body>
</soapenv:Envelope>
3. Donner le code de la classe java ClientCustomerDetails (dans un projet Spring Boot) dans
laquelle vous détaillez la consommation de l’opération getCustomerDetails().
public class ClientCustomer extends WebServiceGatewaySupport {
request.setValue(id);
GetCustomerDetailsResponse response = (GetCustomerDetailsResponse). getWebServiceTemplate()
.marshalSendAndReceive("http://localhost:8080/ws/customers", request,
new SoapActionCallback(
" http://www.tekup.de/ws/CustomerManagementService/GetCustomerDetailsRequest"));
return response;
}
}
2ème Solution : On désire implémenter les opérations qui sont offertes par les web services
OrderManagementService et CustomerManagementService, par un service web Rest en
respectant les contraintes de conception REST (interface uniforme).
4. Donner pour chaque méthode du service REST un exemple d’appel et précisant uniquement
la méthode HTTP utilisée et l’URL complète avec ses paramètres éventuels.
GET http://localhost:8080/api/v1/customers/ GET http://localhost:8080/api/v1/orders/
GET http://localhost:8080/api/v1/customers/{id} POST http://localhost:8080/api/v1/customers/{id}/orders/
POST http://localhost:8080/api/v1/customers/ GET http://localhost:8080/api/v1/orders/{id}
PUT http://localhost:8080/api/v1/customers/{id} GET http://localhost:8080/api/v1/customers/{id}/orders/
DELETE http://localhost:8080/api/v1/customers/{id} PUT http://localhost:8080/api/v1/orders/{id}
DELETE http://localhost:8080/api/v1/orders/{id}
3ème Solution : On veut reprendre cet exemple et proposer un seul endpoint en utilisant
GraphQL (dans un projet Spring Boot). Cet endpoint contient 2 types de données de base :
Customer et Order.
5. Donner un schéma GraphQL pour cet exemple.
enum Status {
received
in_progress
approved
complete
}
type order {
id: ID!
description: String!
amount : Float!
statut: Status!}
type Customer {
id: ID!
firstname: String!
lastname: String!
ordersList: [order!]
}
type Query {
getOrders: [Order]!
getOrderDetails (id: ID):Order
getCustomers :[Customer] !
getCustomersDetails (id: ID): Customer #dans laquelle incluse la reqête getOrdersForCustomers
}
type Mutation {
submitOrder(id: ID, des : String, mt: Float) : Order
updateOrder (id: ID!, s : Status) : Order
cancelOrder (id: ID!) : Boolean
addCustomer (fn : String, ln: String): Customer
updateCustomer (id: ID, fn : String, ln: String ): Customer
deleteCustomer (id: ID): Customer}}
6. Donner le code des classes ClientResolver et ClientMutationResolver.
public class ClientResolver implements GraphQLQueryResolver{
@Autowired
private ClientRepository clientRepository;
@Autowired
private OrderRepository orderRepository;
private CustomerRepository customerRepository;
@Transactional
public Customer addCustomer(Sting fn, String ln){
Customer c=new Customer();
c.setFirstName(fn);
c.setFirstName(ln);
c.setOrderList({});
return Customer.save(c);
}
@Transactional
public Customer updateCustomer(long id, Sting fn, String ln)
{
Customer c= customertRepository.getById(id);
c.setFirstName(fn);
c.setFirstName(ln);
return c;
}
}
@Transactional
public boolean deleteCustomer(Long id) {
customerRepository.deleteById(id);
return true;
}
7. Choisir une solution parmi ces trois, en donnant trois critères pour appuyer votre choix.
Exercice 2
On considère un service Web qui permet aux clients de vendre et d'acheter des produits en ligne.
On s'occupe de la partie de l'application permettant l'ajout, la modification et la consultation de
produits dont les classes (model) sont fournies ci-après.
1. Il vous est demandé d’écrire les classes d’implémentation Java de ce service (model, service
et controller) dans un projet Spring Boot.
On vous fournit les éléments additionnels suivants :
a) le service est disponible à l’URL de base : http://localhost :8080/rest/
b) les produits sont transmis en XML
c) on peut supprimer un produit de 2 manières : en fournissant le produit lui-même ou son
identifiant
d) le id d’un produit modifié, supprimé ou consulté est ajouté comme étape dans le chemin
de l’URL
e) on peut obtenir la liste de tous les produits avec une URL spécifique
f) on peut obtenir la liste des produits correspondant à un des critères de recherche
suivants : le libellé du produit et la ville du propriétaire. Les paramètres sont fournis
comme paramètres de l’URL.
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Personne {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
private String nom;
private String tel;
private String ville;
@OneToMany(mappedBy = " personne")
private Collection<Produit> produits;
}
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Produit {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
private String lib;
private double price;
private String cat;
@ManyToOne
private Personne personne;
}
@Service
public class ProduitServiceImpl implements ProduitService {
@Autowired
private ProduitRepository produitRepository;
@RestController
@RequestMapping("/rest")
Public class ProduitRestController {
@Autowired
private ProduitService produitService;
@GetMapping(path = "/produits/",
produces = {MediaType.APPLICATION_XML_VALUE})
public List<Produit> produitList() {
return produitService.produitList();
}
@GetMapping(path = "/produits/byLib/{lib}",
produces = {MediaType.APPLICATION_XML_VALUE})
public List<Produit> findByLib(@PathVariable String lib) {
return produitService.findByLib(lib);
}
@GetMapping(path = "/produits/byTown/{ville}",
produces = {MediaType.APPLICATION_XML_VALUE})
public List<Produit> findByProdVille(@PathVariable String ville) {
return produitService.findByPersonneVille(ville);
}
2. On désire développer un Rest web service pour effectuer des calculs statistiques sur les
produits créés. Ce service permet d’afficher des statistiques basiques et il va consommer le
service Rest implémenté précédemment. Ecrire les classes d’implémentation Java de ce
service (model, service et controller) dans une projet Spring Boot. La classe Statistique
(model) est fournie ci-après.
count: contient le nombre total des produits.
max et min : contiennent respectivement le prix du
produit le plus cher et le moins cher.
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Personne {
private Long id;
private String nom;
private String tel;
private String ville;
private Collection<Produit> produits;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Produit {
private Long id;
private String lib;
private double price;
private String cat;
private Personne personne;}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Statistique {
private Long count;
private double max;
private double min;
}
public interface StatistiqueService {
public Statistique StatistiqueProduit(); }
@Service
public class StatisticServiceImp implements StatisticService {
@Autowired
private RestTemplate restTemplate;
final String URL_PRODUITS = "http://localhost:8080/rest/produits";
get http://localhost:8080/rest/produits: la liste des produit
@Override
public Statistique StatistiqueProduit(){
ResponseEntity<Produit[ ]> response = restTemplate.getForEntity( URL_PRODUITS,
Produit[].class);
Produit[] produits = response.getBody();