class ImmutableConnection implements Connection {

    public static Connection fromJson(final JsonObject jsonObject) {
        final ConnectionType type = getConnectionTypeOrThrow(jsonObject);
        final MappingContext mappingContext = jsonObject.getValue(JsonFields.MAPPING_CONTEXT)
                .map(ConnectivityModelFactory::mappingContextFromJson)
                .orElse(null);

        final PayloadMappingDefinition payloadMappingDefinition =
                jsonObject.getValue(JsonFields.MAPPING_DEFINITIONS)
                        .map(ImmutablePayloadMappingDefinition::fromJson)
                        .orElse(ConnectivityModelFactory.emptyPayloadMappingDefinition());

        final ConnectionBuilder builder = new Builder(type)
                .id(ConnectionId.of(jsonObject.getValueOrThrow(JsonFields.ID)))
                .connectionStatus(getConnectionStatusOrThrow(jsonObject))
                .uri(jsonObject.getValueOrThrow(JsonFields.URI))
                .sources(getSources(jsonObject))
                .targets(getTargets(jsonObject))
                .name(jsonObject.getValue(JsonFields.NAME).orElse(null))
                .mappingContext(mappingContext)
                .payloadMappingDefinition(payloadMappingDefinition)
                .specificConfig(getSpecificConfiguration(jsonObject))
                .tags(getTags(jsonObject));

        jsonObject.getValue(Connection.JsonFields.LIFECYCLE)
                .flatMap(ConnectionLifecycle::forName).ifPresent(builder::lifecycle);
        jsonObject.getValue(JsonFields.CREDENTIALS).ifPresent(builder::credentialsFromJson);
        jsonObject.getValue(JsonFields.CLIENT_COUNT).ifPresent(builder::clientCount);
        jsonObject.getValue(JsonFields.FAILOVER_ENABLED).ifPresent(builder::failoverEnabled);
        jsonObject.getValue(JsonFields.VALIDATE_CERTIFICATES).ifPresent(builder::validateCertificate);
        jsonObject.getValue(JsonFields.PROCESSOR_POOL_SIZE).ifPresent(builder::processorPoolSize);
        jsonObject.getValue(JsonFields.TRUSTED_CERTIFICATES).ifPresent(builder::trustedCertificates);

        return builder.build();
    }

    private  ImmutableConnection(final Builder builder);

}