RPC
            или социализация приложений
        
        
            RPC
            
                - Remote Procedure Call
 
                - Удалённый вызов процедур
 
            
        
        
            RPC зачем?
            
                - Уменьшить использование ресурсов
 
                - Разнести логику
 
            
        
        
            RPC что?
            
                - это не протокол!
 
                - это набор технологий
 
            
        
        
            RPC из чего состоит
            
                - протокол обмена
 
                - сериализатор данных
 
            
        
        
            RPC протокол обмена
            
                - TCP/UDP
 
                - HTTP(S) [хотя и не является транспортным уровнем ISO/OSI]
 
            
        
        
        
            Особенности вызова
            
                - Асимметричность
 
                - Синхронность
 
            
        
        
            Более сложная реализация
            
                - Разделение адресного пространства
 
                - Транспорт
 
                - аварийные ситуации на одном из концов
 
                - Неоднородность
 
            
        
        
            RMI
            Remote Method Invocation
        
        
            RMI
            
                - API Java
 
                - служит для выполнения кода на другой JVM
 
                - Связь клиент-серверная
 
            
        
        
            RMI что кого
            
                - Объекты передаются по значению (Serializeble)
 
                - Удаленные объекты передаются в виде Stub
 
                - RemoteException
 
                - всё можно найти в java.rmi.*
 
            
        
        
            RMI интерфейс
            
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface RMIInterface extends Remote {
    String sayHello(String name) throws RemoteException;
}
        
        
            RMI сервер
            
import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.*;
public class RMIServer implements RMIInterface {
    public String sayHello(String name) {
        String string = "Hello, " + name + "!";
        return string;
    }
    public static void main(String... args) throws Exception {
        final Registry registry = LocateRegistry.createRegistry(2099);
        final RMIInterface service = new RMIServer();
        Remote stub = UnicastRemoteObject.exportObject(service, 0);
        registry.bind("sample/HelloService", stub);
    }
}
        
        
        
            RMI клиент
            
import java.rmi.registry.*;
public class RMIClient {
    public static void main(String... args) throws Exception {
        Registry registry = LocateRegistry.getRegistry("localhost", 2099);
        RMIInterface service = (RMIInterface) registry
                .lookup("sample/HelloService");
        String[] names = { "John", "Jan", "Иван"};
        for (String name : names) {
            System.out.println(service.sayHello(name));
        }
    }
}
        
        
        
            RMI безопасность
            
grant {
    permission java.net.SocketPermission "127.0.0.1:*", "connect,resolve";
    permission java.net.SocketPermission "127.0.0.1:*", "accept";
};
        
            
grant {
    permission java.security.AllPermission;
};
        
        
        
        
            SOAP
            Simple Object Access Protocol
        
        
        
            SOAP
            
                - расширение XML-RPC
 
                - транспорт HTTP(S), SMTP, FTP, TCP, UDP
 
                - WSDL [Web Service Destribution Language]
 
            
        
        
            SOAP RPC
            
                
                | encoded | 
                    literal | 
                
                
                
                
                    
  
    
      5
      5.0
    
  
        
  | 
                    
  
    
      5
      5.0
    s
  
        
  | 
                
                
            
        
        
        
            SOAP минусы
            
                - избыточость информации
 
                - неторопливсть
 
            
        
        
            SOAP плюсы
            
                - кроссплатформенность
 
                - расширяемость (WS-адресация)
 
                - нейтралитет (протоколы)
 
                - независимость (модель программирования)
 
            
        
        
            SOAP примеры
            
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
@WebService
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface SOAPInterface {
    String sayHello(String name);
}
        
        
        
            SOAP примеры
            
import javax.jws.WebService;
@WebService(endpointInterface = "ru.matmex.rpc.soap.SOAPInterface")
public class SOAPImpl implements SOAPInterface {
    @Override
    public String sayHello(String name) {
        return "Hello " + name + "!";
    }
}
        
        
        
            SOAP примеры
            
import javax.xml.ws.Endpoint;
public class SOAPServer {
    public static void main(String... args) {
        Endpoint.publish("http://localhost:9999/ws/hello", new SOAPImpl());
    }
}
        
        
        
            SOAP примеры
            
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
public class SOAPClient {
    public static void main(String... args) throws Exception {
        URL url = new URL("http://localhost:9999/ws/hello?wsdl");
        QName qname = new QName("http://soap.rpc.matmex.ru/", "SOAPImplService");
        Service service = Service.create(url, qname);
        SOAPInterface hello = service.getPort(SOAPInterface.class);
        System.out.println(hello.sayHello("Magaz"));
    }
}
        
        
        
            SOAP примеры
            
wsimport -keep http://localhost:9999/ws/hello?wsdl
        
        
        
            SOAP примеры
            
@WebServiceClient(name = "SOAPImplService",
                targetNamespace = "http://soap.rpc.matmex.ru/",
                wsdlLocation = "http://localhost:9999/ws/hello?wsdl")
public class SOAPImplService extends Service {/**/}
@WebService(name = "SOAPInterface", targetNamespace = "http://soap.rpc.matmex.ru/")
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface SOAPInterface {/**/}
        
        
        
            SOAP примеры
            
public class SOAPClientWSImport {
    public static void main(String... args) {
        SOAPImplService helloService = new SOAPImplService();
        SOAPInterface hello = helloService.getSOAPImplPort();
        System.out.println(hello.sayHello("Magaz"));
    }
}
        
        
        
            HTTP
            HyperText Transfer Protocol
            протокол передачи гипертекста
        
        
            HTTP
            
                - протокол прикладного уровня
 
                - клиент-север, запрос-ответ
 
            
        
        
            HTTP методы
            
                - GET
 
                - POST
 
                - PUT
 
                - DELETE
 
                - HEAD
 
                - OPTIONS
 
            
        
        
            HTTP заголовки
            
                - Host
 
                - User-Agent
 
                - Accept
 
                - Content-Type
 
                - DoNotTrack
 
            
        
        
            HTTP коды ответа
            
                - 1xx - информационные
 
                - 2xx - успешно
 
                - 3xx - перенаправление
 
                - 4xx - ошибка клиента
 
                - 5xx - ошибка сервера
 
            
    
        
        
            HTTP запрос
            
GET /search?q=REST HTTP/2
Host: www.google.com
Accept-Encoding: deflate, gzip, br
User-Agent: Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:65.0) Gecko/20100101 Firefox/65.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Connection: keep-alive
        
        
            HTTP ответ
            
HTTP/2 200 
content-type: text/html; charset=UTF-8
date: Tue, 12 Mar 2019 20:12:12 GMT
expires: -1
cache-control: private, max-age=0
trailer: X-Google-GFE-Current-Request-Cost-From-GWS
strict-transport-security: max-age=31536000
content-encoding: br
server: gws
x-xss-protection: 1; mode=block
x-frame-options: SAMEORIGIN
        
        
            REST
            Representational State Transfer
            передача состояния представления
        
        
            Требования к REST
            
                - Клиент-сервер
 
                - Отсутствие состояния
 
                - Кэширование
 
                - Единообразие интерфейса
                    
                        - Идентификация ресурсов
 
                        - Манипуляция ресурсами через представление
 
                        - «Самоописываемые» сообщения
 
                        - Гипермедиа (HATEOAS)
 
                    
                 
                - Слои
 
            
        
        
            Характеризуется
            
                
                
                    | метод запроса | 
                    GET, POST, DELETE | 
                
                
                    | путь запроса | 
                    /objects/list, /objects/100500 | 
                
                
                    | тело запросв | 
                    форма, json, xml | 
                
                
                    | код ответа | 
                    200 OK, 404 NotFound | 
                
                
                    | тело ответа | 
                    json, html, xml | 
                
                
            
        
        
            REST и Java
            
                - JAX-RS
 
                - Spring Framework
 
                - и другое
 
            
        
        
            JAX-RS
            
                - Java API for RESTful Web Services
 
                - JavaEE
 
            
        
        
            JAX-RS аннотации
            
                - @Path
 
                - @GET, @PUT, @POST, @DELETE, @HEAD
 
                - @Produces
 
                - @Consumes
 
            
        
        
            JAX-RS аннотации
            
                - @PathParam
 
                - @QueryParam
 
                - @HeaderParam
 
                - @CookieParam
 
                - @FormParam
 
                - @DefaultValue
 
                - @Context
 
            
        
        
            SpringFramework
            
                - @RequestMapping
 
                - @GetMapping, @PostMapping, @PutMapping, @PatchMapping, @DeleteMapping
 
            
        
        
            
            
                - @PathVariable
 
                - @RequestAttribute
 
                - @RequestBody
 
                - @RequestParam
 
                - @SessionAttribute(s)
 
            
        
        
            JAX-RS пример
            
@Path("/greetings")
public class JaxRsController {
    @GET
    @Path("/{name}")
    @Produces(MediaType.TEXT_PLAIN)
    public Response greeting(@PathParam("name") String name) {
        String greeting = "Hello " + name;
        return Response.ok(greeting).build();
    }
}
      
        
        
            Spring пример 1
            
@RestController
@RequestMapping("/greetings")
public class SpringRestController {
    @RequestMapping(method = RequestMethod.GET,
                    value = "/{name}",
                    produces = MediaType.TEXT_PLAIN_VALUE)
    public ResponseEntity< ? > greeting(@PathVariable String name) {
        String greeting = "Hello " + name;
        return new ResponseEntity<>(greeting, HttpStatus.OK);
    }
}
      
        
        
            Spring пример 2
            
@RestController
public class GreetingController {
    @RequestMapping("/greeting")
    public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) {
        return new Greeting("Hello " + name);
    }
}
      
        
        
            Spring пример. Клиент
            
public static void main(String... args) {
    RestTemplate restTemplate = new RestTemplate();
    String message = restTemplate.getForObject("http://localhost/greetings/Bob", Sting.class);
    log.info(message);
    Greeting greeting = restTemplate.getForObject("http://localhost/greeting?name=Bob", Greeting.class);
    // {"message": "Hello Bob"}
    log.info(greeting.getMessage());
}
      
        
        
            HATEOAS
            Hypermedia as the Engine of Application State
            
                - клиент обращается к фиксированному URL
 
                - клиент может ничего не знать о сервере, кроме входящего URL
 
            
                
        
            HATEOAS пример
            
{
  "content":"Hello, User!",
  "_links":{
    "self":{
      "href":"http://localhost:8080/greeting/User"
    },
    "farewell":{
      "href":"http://localhost:8080/farewell/User"
    }
  }
}
      
        
		
            Документация REST
            
                - Руководство по быстрому старту
 
                - Описание точек входа (edpoints)
 
                - Примеры запросов
 
				- Примеры ответов
 
            
        
		
            OpenAPI / Swagger
            
                - Описание на json либо yaml
 
                - Поддерживаетя большим количеством языков
 
                - Автогенерация
 
				- Множестов утилит
 
            
        
		
            Пример 1
            
"/greetings/{name}": {
  "get": {
    "parameters": [{
        "name": "name",
        "in": "path",
        "schema": {
          "type": "string"
        }}],
    "responses": {
      "200": {
        "description": "OK",
        "content": {"text/plain": {"schema": {"type": "object"}}}
      }}}
}
			
        
		
            Пример 2
            
"/greeting": {
  "get": {
    "parameters": [{
        "name": "name",
        "in": "query",
        "schema": { "type": "string"}
      }],
    "responses": {
      "200": {
        "description": "OK",
        "content": {"*/*": {"schema": {"$ref": "#/components/schemas/Greeting"}}}
      }}}}
			
        
		
            Пример Greeting
            
"Greeting": {
  "title": "Greeting",
  "type": "object",
  "properties": {
    "message": {
    "type": "string"
    }
  }
}
			
        		
		
            Подключаем в Spring
            
	io.springfox
	springfox-boot-starter
	3.0.0
			
        	
		
            Подключаем в Spring
            
	io.springfox
	springfox-swagger-ui
	3.0.0
			
        	
		
            API UI
			
        	
		
            Генерация OnLine
			
        
        
            Ппример 1 интерфейс
            
@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.SpringCodegen", date = "2019-09-21T17:43:13.247Z[GMT]")
@Api(value = "greetings", description = "the greetings API")
public interface GreetingsApi {
    @ApiOperation(value = "greeting", nickname = "greetingUsingGET1", notes = "", response = Object.class, tags = {"spring-rest-controller",})
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "OK", response = Object.class),
            @ApiResponse(code = 401, message = "Unauthorized"),
            @ApiResponse(code = 403, message = "Forbidden"),
            @ApiResponse(code = 404, message = "Not Found")})
    @RequestMapping(value = "/greetings/{name}",
            produces = {"text/plain"},
            method = RequestMethod.GET)
    ResponseEntity<Object> greetingUsingGET1(@ApiParam(value = "name", required = true) @PathVariable("name") String name);
}
			
        
        
        Пример 1 реализация
        
public ResponseEntity<Object> greetingUsingGET1(@ApiParam(value = "name", required = true) @PathVariable("name") String name) {
    String accept = request.getHeader("Accept");
    if (accept != null && accept.contains("application/json")) {
        try {
            return new ResponseEntity<Object>(objectMapper.readValue("{ }", Object.class), HttpStatus.NOT_IMPLEMENTED);
        } catch (IOException e) {
            log.error("Couldn't serialize response for content type application/json", e);
            return new ResponseEntity<Object>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
    return new ResponseEntity<Object>(HttpStatus.NOT_IMPLEMENTED);
}
			
    
        
            gRPC
            
                - Google
 
                - Protocol Buffers v3
 
                - HTTP/2
 
            
        
        
            Protocol Buffers
            
                - протокол сериализации
 
                - проще, быстрее, однозначнее XML
 
                - необходима реализация под каждый язык
 
            
        
        
            HTTP/2
            
                - только HTTPS
 
                - одно соединение для всех запросов
 
            
        
        
            gRPC пример описания
            
service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
  string name = 1;
}
message HelloReply {
  string message = 1;
}
        
        
            Типы gRPC
            
                - Unary RPC
 
                - Server streaming RPC
 
                - Client streaming RPC
 
                - Bidirectional streaming
 
            
        
        
            Что есть еще в gRPC
            
                - балансировка
 
                - Interceptors
 
            
        
        
            gRPC клиент
public class HelloWorldClient {
  public static void main(String[] args) throws Exception {
    ManagedChannel channel = ManagedChannelBuilder
        .forAddress("localhost", 50051).usePlaintext().build();
    GreeterGrpc.GreeterBlockingStub blockingStub = GreeterGrpc.newBlockingStub(channel);
    try {
      HelloRequest request = HelloRequest.newBuilder().setName(name).build();
      HelloReply response;
      try {
        response = blockingStub.sayHello("Magaz");
      } catch (StatusRuntimeException e) {
        System.err.println("RPC failed: " + e.getStatus());return;
      }
      System.out.println("Greeting: " + response.getMessage());
    } finally {
      channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
    }
  }
}
        
        
            gRPC сервер
import io.grpc.*;
import io.grpc.stub.StreamObserver;
import java.io.IOException;
public class HelloWorldServer {
  public static void main(String[] args) throws IOException, InterruptedException {
    Server server = ServerBuilder.forPort(50051)
            .addService(new GreeterImpl()).build().start();
    server.awaitTermination();
  }
  static class GreeterImpl extends GreeterGrpc.GreeterImplBase {
    @Override
    public void sayHello(HelloRequest req, StreamObserver< HelloReply > responseObserver) {
      HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build();
      responseObserver.onNext(reply);
      responseObserver.onCompleted();
    }
  }
}
        
        
        
            JMS
            
                - Это не RPC
 
                - Является частью JDK
 
                - Топики
 
                - Очереди
 
            
        
        
            JMS основа
import javax.jms.*;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
class ConsumerOrProducer {
    public static void main(String[] args) throws JMSException {
        ConnectionFactory connectionFactory 
          = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_BROKER_URL);
		Connection connection = connectionFactory.createConnection();
        connection.start();
        Session session = connection
                      .createSession(false, Session.AUTO_ACKNOWLEDGE);
        Destination destination = null;
        if("QUEUE".equalsIgnoreCase(System.getProperty("amq"))) {        	
        	destination = session.createQueue("LolQueue");	
        }else{        	
        	destination = session.createTopic("LolTopik");        	
        }
        /*
        ........................................
        */
        connection.close();
    }
}
        
        
        
            JMS прием
MessageConsumer consumer = session.createConsumer(destination);
String body;
do {
    Message msg = consumer.receive();
    body = ((TextMessage) msg).getText();
    
    System.out.println("Received = "+body);
    
}while (!body.equalsIgnoreCase("GoHome!"));
        
        
        
            JMS отправка
        MessageProducer producer = session.createProducer(destination);
Console c = System.console();
String response;
do {
    
    response = c.readLine("Enter message: ");
    
    TextMessage msg = session.createTextMessage(response);
    producer.send(msg);
    
} while (!response.equalsIgnoreCase("GoHome!"));