@Override
    public Response onApply(WriteRequest request) {
        final Lock lock = readLock;
        lock.lock();
        try {
            final InstanceStoreRequest instanceRequest = serializer.deserialize(request.getData().toByteArray());
            final DataOperation operation = DataOperation.valueOf(request.getOperation());
            switch (operation) {
                case ADD:
                    onInstanceRegister(instanceRequest.service, instanceRequest.instance,
                            instanceRequest.getClientId());
                    break;
                case DELETE:
                    onInstanceDeregister(instanceRequest.service, instanceRequest.getClientId());
                    break;
                case CHANGE:
                    if (instanceAndServiceExist(instanceRequest)) {
                        onInstanceRegister(instanceRequest.service, instanceRequest.instance,
                                instanceRequest.getClientId());
                    }
                    break;
                default:
                    return Response.newBuilder().setSuccess(false).setErrMsg("unsupport operation : " + operation)
                            .build();
            }
            return Response.newBuilder().setSuccess(true).build();
        } catch (Exception e) {
            Loggers.RAFT.warn("Persistent client operation failed. ", e);
            return Response.newBuilder().setSuccess(false)
                    .setErrMsg("Persistent client operation failed. " + e.getMessage()).build();
        } finally {
            lock.unlock();
        }
    }
@Test
    void testOnApply() {
        PersistentClientOperationServiceImpl.InstanceStoreRequest request = new PersistentClientOperationServiceImpl.InstanceStoreRequest();
        Service service1 = Service.newService("A", "B", "C");
        request.setService(service1);
        request.setClientId("xxxx");
        request.setInstance(new Instance());
        
        Mockito.when(serializer.deserialize(Mockito.any())).thenReturn(request);
        
        Mockito.when(clientManager.contains(Mockito.anyString())).thenReturn(true);
        
        IpPortBasedClient ipPortBasedClient = Mockito.mock(IpPortBasedClient.class);
        Mockito.when(clientManager.getClient(Mockito.anyString())).thenReturn(ipPortBasedClient);
        
        WriteRequest writeRequest = WriteRequest.newBuilder().setOperation(DataOperation.ADD.name()).build();
        Response response = persistentClientOperationServiceImpl.onApply(writeRequest);
        assertTrue(response.getSuccess());
        assertTrue(ServiceManager.getInstance().containSingleton(service1));
        writeRequest = WriteRequest.newBuilder().setOperation(DataOperation.DELETE.name()).build();
        response = persistentClientOperationServiceImpl.onApply(writeRequest);
        assertTrue(response.getSuccess());
        ServiceManager.getInstance().removeSingleton(service1);
        
        writeRequest = WriteRequest.newBuilder().setOperation(DataOperation.VERIFY.name()).build();
        response = persistentClientOperationServiceImpl.onApply(writeRequest);
        assertFalse(response.getSuccess());
        
        writeRequest = WriteRequest.newBuilder().setOperation(DataOperation.CHANGE.name()).build();
        response = persistentClientOperationServiceImpl.onApply(writeRequest);
        assertTrue(response.getSuccess());
        assertFalse(ServiceManager.getInstance().containSingleton(service1));
    }