Exemplo n.º 1
0
    def find_conn(self, mconns, vbucket_id, msgs):
        bucket = self.sink_map['buckets'][0]

        vBucketMap = bucket['vBucketServerMap']['vBucketMap']
        serverList = bucket['vBucketServerMap']['serverList']

        if vbucket_id > len(vBucketMap):
            return "error: map missing vbucket_id: " + str(vbucket_id) + \
                "; perhaps your source does not have vbuckets" + \
                "; if so, try using moxi (HOST:11211) as a destination", None

        # Primary server for a vbucket_id is the 0'th entry.
        host_port = serverList[vBucketMap[vbucket_id][0]]

        conn = mconns.get(host_port, None)
        if not conn:
            host, port = pump.hostport(host_port, 11210)
            if self.opts.ssl:
                port = couchbaseConstants.SSL_PORT
            bucket = bucket['name']
            rv, conn = CBSink.connect_mc(host, port, self.opts.username, self.opts.password, bucket)
            if rv != 0:
                logging.error("error: CBSink.connect() for send: " + rv)
                return rv, None
            mconns[host_port] = conn

            if self.opts.collection:
                try:
                    # HELO collections
                    conn.helo([couchbaseConstants.HELO_COLLECTIONS])
                except Exception, e:
                    logging.warn("fail to call hello command, maybe it is not supported")
                    pass

            self.add_start_event(conn)
Exemplo n.º 2
0
    def provide_index(opts, source_spec, source_bucket, source_map):
        err, index_server = pump.filter_server(opts, source_spec, 'index')
        if err or not index_server:
            logging.warning("could not find index server:%s" % err)
            return 0, None

        spec_parts = source_map.get('spec_parts')
        if not spec_parts:
            return "error: no design spec_parts", None
        host, port, user, pswd, path = spec_parts
        host, port = pump.hostport(index_server)
        err, ddocs_json, ddocs = \
            pump.rest_request_json(host, couchbaseConstants.INDEX_PORT, user, pswd, opts.ssl,
                                   "/getIndexMetadata?bucket=%s" % (source_bucket['name']),
                                   reason="provide_index")
        if err:
            return err, None

        return 0, json.dumps(ddocs["result"])
Exemplo n.º 3
0
    def provide_index(opts, source_spec, source_bucket, source_map):
        err, index_server = pump.filter_server(opts, source_spec, 'index')
        if err or not index_server:
            logging.warning("could not find index server:%s" % err)
            return 0, None

        spec_parts = source_map.get('spec_parts')
        if not spec_parts:
            return "error: no design spec_parts", None
        host, port, user, pswd, path = spec_parts
        host, port = pump.hostport(index_server)
        err, ddocs_json, ddocs = \
            pump.rest_request_json(host, couchbaseConstants.INDEX_PORT, user, pswd, opts.ssl,
                                   "/getIndexMetadata?bucket=%s" % (source_bucket['name']),
                                   reason="provide_index")
        if err:
            return err, None

        return 0, json.dumps(ddocs["result"])
Exemplo n.º 4
0
    def find_conn(self, mconns, vbucket_id, msgs):
        bucket = self.sink_map['buckets'][0]

        vBucketMap = bucket['vBucketServerMap']['vBucketMap']
        serverList = bucket['vBucketServerMap']['serverList']

        if vbucket_id > len(vBucketMap):
            return "error: map missing vbucket_id: " + str(vbucket_id) + \
                "; perhaps your source does not have vbuckets" + \
                "; if so, try using moxi (HOST:11211) as a destination", None

        # Primary server for a vbucket_id is the 0'th entry.
        host_port = serverList[vBucketMap[vbucket_id][0]]

        conn = mconns.get(host_port, None)
        if not conn:
            host, port = pump.hostport(host_port, 11210)
            if self.opts.ssl:
                port = couchbaseConstants.SSL_PORT
            bucket = bucket['name']
            username = self.opts.username
            password = self.opts.password
            if self.opts.username_dest is not None and self.opts.password_dest is not None:
                username = self.opts.username_dest
                password = self.opts.password_dest
            rv, conn = CBSink.connect_mc(host, port, username, password, bucket, self.opts.ssl,
                                         self.opts.no_ssl_verify, self.opts.cacert,
                                         collections=self.opts.collection!=None)
            if rv != 0:
                logging.error("error: CBSink.connect() for send: " + rv)
                return rv, None
            mconns[host_port] = conn
            if self.opts.collection:
                try:
                    # HELO collections
                    conn.helo([couchbaseConstants.HELO_COLLECTIONS])
                except Exception as e:
                    logging.warn("fail to call hello command, maybe it is not supported")
                    pass

            self.add_start_event(conn)
        return 0, conn
Exemplo n.º 5
0
    def find_conn(self, mconns, vbucket_id, msgs):
        bucket = self.sink_map['buckets'][0]

        vBucketMap = bucket['vBucketServerMap']['vBucketMap']
        serverList = bucket['vBucketServerMap']['serverList']

        if vbucket_id > len(vBucketMap):
            return "error: map missing vbucket_id: " + str(vbucket_id) + \
                "; perhaps your source does not have vbuckets" + \
                "; if so, try using moxi (HOST:11211) as a destination", None

        # Primary server for a vbucket_id is the 0'th entry.
        host_port = serverList[vBucketMap[vbucket_id][0]]

        conn = mconns.get(host_port, None)
        if not conn:
            host, port = pump.hostport(host_port, 11210)
            if self.opts.ssl:
                port = couchbaseConstants.SSL_PORT
            user = bucket['name']
            pswd = bucket['saslPassword']
            rv, conn = CBSink.connect_mc(host, port, user, pswd)
            if rv != 0:
                logging.error("error: CBSink.connect() for send: " + rv)
                return rv, None
            mconns[host_port] = conn

            #check if we need to calll hello command
            for i, msg in enumerate(msgs):
                msg_format_length = len(msg)
                if msg_format_length > 8:
                    try:
                        conn.hello()
                    except Exception, e:
                        logging.warn(
                            "fail to call hello command, maybe it is not supported"
                        )
                        pass
                break

            self.add_start_event(conn)
Exemplo n.º 6
0
    def find_conn(self, mconns, vbucket_id, msgs):
        bucket = self.sink_map['buckets'][0]

        vBucketMap = bucket['vBucketServerMap']['vBucketMap']
        serverList = bucket['vBucketServerMap']['serverList']

        if vbucket_id > len(vBucketMap):
            return "error: map missing vbucket_id: " + str(vbucket_id) + \
                "; perhaps your source does not have vbuckets" + \
                "; if so, try using moxi (HOST:11211) as a destination", None

        # Primary server for a vbucket_id is the 0'th entry.
        host_port = serverList[vBucketMap[vbucket_id][0]]

        conn = mconns.get(host_port, None)
        if not conn:
            host, port = pump.hostport(host_port, 11210)
            if self.opts.ssl:
                port = couchbaseConstants.SSL_PORT
            user = bucket['name']
            pswd = bucket['saslPassword']
            rv, conn = CBSink.connect_mc(host, port, user, pswd)
            if rv != 0:
                logging.error("error: CBSink.connect() for send: " + rv)
                return rv, None
            mconns[host_port] = conn

            #check if we need to calll hello command
            for i, msg in enumerate(msgs):
                msg_format_length = len(msg)
                if msg_format_length > 8:
                    try:
                        conn.hello()
                    except Exception, e:
                        logging.warn("fail to call hello command, maybe it is not supported")
                        pass
                break

            self.add_start_event(conn)
Exemplo n.º 7
0
    def get_dcp_conn(self):
        """Return previously connected dcp conn."""

        if not self.dcp_conn:
            host, _ = pump.hostport(self.source_node['hostname'])
            port = self.source_node['ports']['direct']
            username = self.opts.username
            password = self.opts.password
            bucket = str(self.source_bucket.get("name"))
            if self.opts.ssl:
                port = couchbaseConstants.SSL_PORT

            if getattr(self, 'alt_add', None):
                if 'alternateAddresses' in self.source_node:
                    host = self.source_node['alternateAddresses']['external'][
                        'hostname']
                    if 'ports' not in self.source_node['alternateAddresses'][
                            'external']:
                        return [
                            'no data port available in external address: {}'.
                            format(host)
                        ], None

                    alterante_ports = self.source_node['alternateAddresses'][
                        'external']['ports']
                    if self.opts.ssl:
                        if 'kvSSL' not in alterante_ports:
                            return [
                                'Secure data port not available in external host: {}'
                                .format(host)
                            ]
                        port = alterante_ports['kvSSL']
                    elif 'kv' not in alterante_ports:
                        return [
                            'Data port not available in external host: {}'.
                            format(host)
                        ]
                    else:
                        port = alterante_ports['kv']
                else:
                    return [
                        'alterante address not available in node: {}'.format(
                            self.source_node['otpNode'])
                    ], None

            logging.debug(f'  DCPStreamSource connecting mc: {host}:{port!s}')

            err, self.dcp_conn = pump.get_mcd_conn(host, port, username,
                                                   password, bucket,
                                                   self.opts.ssl,
                                                   self.opts.no_ssl_verify,
                                                   self.opts.cacert)
            if err:
                return err, None

            err, self.mem_conn = pump.get_mcd_conn(host, port, username,
                                                   password, bucket,
                                                   self.opts.ssl,
                                                   self.opts.no_ssl_verify,
                                                   self.opts.cacert)
            if err:
                return err, None

            flags = couchbaseConstants.FLAG_DCP_PRODUCER | couchbaseConstants.FLAG_DCP_XATTRS
            extra = struct.pack(couchbaseConstants.DCP_CONNECT_PKT_FMT, 0,
                                flags)
            try:
                opaque = self.r.randint(0, 2**32)
                self.dcp_conn._send_cmd(couchbaseConstants.CMD_DCP_CONNECT,
                                        self.dcp_name.encode(), b'', opaque,
                                        extra)
                self.dcp_conn._handle_single_response(opaque)

                opaque = self.r.randint(0, 2**32)
                self.dcp_conn._send_cmd(
                    couchbaseConstants.CMD_DCP_CONTROL,
                    couchbaseConstants.KEY_DCP_CONNECTION_BUFFER_SIZE,
                    str(self.batch_max_bytes * 10).encode(), opaque)
                self.dcp_conn._handle_single_response(opaque)

                opaque = self.r.randint(0, 2**32)
                self.dcp_conn._send_cmd(couchbaseConstants.CMD_DCP_CONTROL,
                                        couchbaseConstants.KEY_DCP_NOOP,
                                        b'true', opaque)
                self.dcp_conn._handle_single_response(opaque)

                opaque = self.r.randint(0, 2**32)
                self.dcp_conn._send_cmd(
                    couchbaseConstants.CMD_DCP_CONTROL,
                    couchbaseConstants.KEY_DCP_NOOP_INTERVAL, b'180', opaque)
                self.dcp_conn._handle_single_response(opaque)
            except EOFError:
                return "error: Fail to set up DCP connection"
            except cb_bin_client.MemcachedError:
                return "error: DCP connect memcached error"
            except socket.error:
                return "error: DCP connection error"
            try:
                opaque = self.r.randint(0, 2**32)
                self.dcp_conn._send_cmd(
                    couchbaseConstants.CMD_DCP_CONTROL,
                    couchbaseConstants.KEY_DCP_EXT_METADATA,
                    bool_to_str(True).encode(), opaque)
                self.dcp_conn._handle_single_response(opaque)
            except EOFError:
                return "error: Fail to set up DCP connection"
            except cb_bin_client.MemcachedError:
                pass
            except socket.error:
                return "error: DCP connection error"

            self.running = True
            self.start()

            self.add_start_event(self.dcp_conn)
            self.setup_dcp_streams()
        return 0
Exemplo n.º 8
0
    def find_conn(self, mconns: Dict[str, cb_bin_client.MemcachedClient], vbucket_id: int, msgs) -> \
            Tuple[couchbaseConstants.PUMP_ERROR, Optional[cb_bin_client.MemcachedClient]]:
        bucket = self.sink_map['buckets'][0]

        vbucket_map = bucket['vBucketServerMap']['vBucketMap']
        server_list = bucket['vBucketServerMap']['serverList']

        if vbucket_id > len(vbucket_map):
            return f'error: map missing vbucket_id: {vbucket_id!s}' \
                f'; perhaps your source does not have vbuckets; if so, try using moxi (HOST:11211) as a destination',\
                   None

        # Primary server for a vbucket_id is the 0'th entry.
        host_port = server_list[vbucket_map[vbucket_id][0]]
        server_host, _ = pump.hostport(host_port)
        if getattr(self, 'alt_add', None):
            host = None
            port = None
            for n in bucket['nodes']:
                if 'alternateAddresses' not in n:
                    # we could raise an error if one of the nodes does not have an alternate address
                    continue

                node_host = '127.0.0.1'
                if 'hostname' in n:
                    node_host, _ = pump.hostport(n['hostname'])

                # if server does not match continue
                if node_host != server_host:
                    continue

                # if correct node check alternate address
                host = n['alternateAddresses']['external']['hostname']
                if self.opts.ssl:
                    if 'kvSSL' in n['alternateAddresses']['external']['ports']:
                        port = n['alternateAddresses']['external']['ports'][
                            'kvSSL']
                    else:
                        return 'Host does not have a secure data port', None
                elif 'kv' in n['alternateAddresses']['external']['ports']:
                    port = n['alternateAddresses']['external']['ports']['kv']
                else:
                    return 'Host does not have data service', None
                break

            if host is None or port is None:
                return 'No alternate address information found for host "{}"'.format(
                    host_port), None

            # wrap ipv6 address with []
            if ':' in host and not host.startswith('['):
                host = '[' + host + ']'

            try:
                int(port)
            except ValueError:
                return 'Invalid port "{}"'.format(port), None

            host_port = host + ":" + str(port)

        logging.debug('Conencting to host "{}" for vbucket {}'.format(
            host_port, vbucket_id))

        conn = mconns.get(host_port, None)
        if conn is None:
            host, port = pump.hostport(host_port, 11210)
            if self.opts.ssl:
                port = couchbaseConstants.SSL_PORT
            bucket = bucket['name']
            username = self.opts.username
            password = self.opts.password
            if self.opts.username_dest is not None and self.opts.password_dest is not None:
                username = self.opts.username_dest
                password = self.opts.password_dest
            rv, conn = CBSink.connect_mc(host,
                                         port,
                                         username,
                                         password,
                                         bucket,
                                         self.opts.ssl,
                                         self.opts.no_ssl_verify,
                                         self.opts.cacert,
                                         collections=self.opts.collection
                                         is not None)
            if rv != 0:
                logging.error(f'error: CBSink.connect() for send: {rv}')
                return rv, None
            if conn is not None:
                mconns[host_port] = conn
                self.add_start_event(conn)
        return 0, conn
Exemplo n.º 9
0
    def get_dcp_conn(self):
        """Return previously connected dcp conn."""

        if not self.dcp_conn:
            host, _ = pump.hostport(self.source_node['hostname'])
            port = self.source_node['ports']['direct']
            username = self.opts.username
            password = self.opts.password
            bucket = str(self.source_bucket.get("name"))
            if self.opts.ssl:
                port = couchbaseConstants.SSL_PORT

            logging.debug("  DCPStreamSource connecting mc: " + host + ":" +
                          str(port))

            err, self.dcp_conn = pump.get_mcd_conn(host, port, username,
                                                   password, bucket,
                                                   self.opts.ssl,
                                                   self.opts.no_ssl_verify,
                                                   self.opts.cacert)
            if err:
                return err, None

            err, self.mem_conn = pump.get_mcd_conn(host, port, username,
                                                   password, bucket,
                                                   self.opts.ssl,
                                                   self.opts.no_ssl_verify,
                                                   self.opts.cacert)
            if err:
                return err, None

            flags = couchbaseConstants.FLAG_DCP_PRODUCER | couchbaseConstants.FLAG_DCP_XATTRS
            extra = struct.pack(couchbaseConstants.DCP_CONNECT_PKT_FMT, 0,
                                flags)
            try:
                opaque = self.r.randint(0, 2**32)
                self.dcp_conn._sendCmd(couchbaseConstants.CMD_DCP_CONNECT, self.dcp_name, \
                                       '', opaque, extra)
                self.dcp_conn._handleSingleResponse(opaque)

                buff_size = 0
                if self.flow_control:
                    # set connection buffer size. Considering header size, we roughly
                    # set the total received package size as 10 times as value size.
                    buff_size = self.batch_max_bytes * 10

                opaque = self.r.randint(0, 2**32)
                self.dcp_conn._sendCmd(
                    couchbaseConstants.CMD_DCP_CONTROL,
                    couchbaseConstants.KEY_DCP_CONNECTION_BUFFER_SIZE,
                    str(self.batch_max_bytes * 10), opaque)
                self.dcp_conn._handleSingleResponse(opaque)

                opaque = self.r.randint(0, 2**32)
                self.dcp_conn._sendCmd(couchbaseConstants.CMD_DCP_CONTROL,
                                       couchbaseConstants.KEY_DCP_NOOP, "true",
                                       opaque)
                self.dcp_conn._handleSingleResponse(opaque)

                opaque = self.r.randint(0, 2**32)
                self.dcp_conn._sendCmd(
                    couchbaseConstants.CMD_DCP_CONTROL,
                    couchbaseConstants.KEY_DCP_NOOP_INTERVAL, str(180), opaque)
                self.dcp_conn._handleSingleResponse(opaque)
            except EOFError:
                return "error: Fail to set up DCP connection"
            except cb_bin_client.MemcachedError:
                return "error: DCP connect memcached error"
            except socket.error:
                return "error: DCP connection error"
            try:
                opaque = self.r.randint(0, 2**32)
                self.dcp_conn._sendCmd(couchbaseConstants.CMD_DCP_CONTROL,
                                       couchbaseConstants.KEY_DCP_EXT_METADATA,
                                       bool_to_str(True), opaque)
                self.dcp_conn._handleSingleResponse(opaque)
            except EOFError:
                return "error: Fail to set up DCP connection"
            except cb_bin_client.MemcachedError:
                pass
            except socket.error:
                return "error: DCP connection error"

            self.running = True
            self.start()

            self.add_start_event(self.dcp_conn)
            self.setup_dcp_streams()
        return 0
Exemplo n.º 10
0
            if not sd:
               return 0
            print json.dumps(sd, indent=2)
        except ValueError, e:
            return "error: could not parse source design; exception: %s" % (e)

        err, index_server = pump.filter_server(opts, sink_spec, 'index')
        if err or not index_server:
            logging.error("could not find index server")
            return 0

        spec_parts = pump.parse_spec(opts, sink_spec, 8091)
        if not spec_parts:
            return "error: design sink no spec_parts: " + sink_spec
        host, port, user, pswd, path = spec_parts
        host,port = pump.hostport(index_server)
        sink_bucket = sink_map['buckets'][0]
        url = "/restoreIndexMetadata?bucket=%s" % sink_bucket['name']
        #post_headers = {"Content-type": "application/x-www-form-urlencoded"}
        err, conn, response = \
            pump.rest_request(host, couchbaseConstants.INDEX_PORT, user, pswd, opts.ssl,
                              url, method='POST',
                              #body=urllib.urlencode(sd),
                              body=json.dumps(sd),
                              #headers=post_headers,
                              reason='restore index')
        print response
        return 0

    @staticmethod
    def consume_design(opts, sink_spec, sink_map,
Exemplo n.º 11
0
    def get_dcp_conn(self):
        """Return previously connected dcp conn."""

        if not self.dcp_conn:
            host, _  = pump.hostport(self.source_node['hostname'])
            port = self.source_node['ports']['direct']
            username = self.opts.username
            password = self.opts.password
            bucket = str(self.source_bucket.get("name"))
            if self.opts.ssl:
                port = couchbaseConstants.SSL_PORT

            if getattr(self, 'alt_add', None):
                if 'alternateAddresses' in self.source_node:
                    host = self.source_node['alternateAddresses']['external']['hostname']
                    if 'ports' not in self.source_node['alternateAddresses']['external']:
                        return ['no data port available in external address: {}'. format(host)], None

                    alterante_ports = self.source_node['alternateAddresses']['external']['ports']
                    if self.opts.ssl:
                        if 'kvSSL' not in alterante_ports:
                            return ['Secure data port not available in external host: {}'.format(host)]
                        port = alterante_ports['kvSSL']
                    elif 'kv' not in alterante_ports:
                        return ['Data port not available in external host: {}'.format(host)]
                    else:
                        port = alterante_ports['kv']
                else:
                    return ['alterante address not available in node: {}'.format(self.source_node['otpNode'])], None

            logging.debug(f'  DCPStreamSource connecting mc: {host}:{port!s}')

            err, self.dcp_conn = pump.get_mcd_conn(host, port, username, password, bucket, self.opts.ssl,
                                                   self.opts.no_ssl_verify, self.opts.cacert)
            if err:
                return err, None

            err, self.mem_conn = pump.get_mcd_conn(host, port, username, password, bucket, self.opts.ssl,
                                                   self.opts.no_ssl_verify, self.opts.cacert)
            if err:
                return err, None

            flags = couchbaseConstants.FLAG_DCP_PRODUCER | couchbaseConstants.FLAG_DCP_XATTRS
            extra = struct.pack(couchbaseConstants.DCP_CONNECT_PKT_FMT, 0, flags)
            try:
                opaque = self.r.randint(0, 2**32)
                self.dcp_conn._sendCmd(couchbaseConstants.CMD_DCP_CONNECT, self.dcp_name.encode() , b'', opaque, extra)
                self.dcp_conn._handleSingleResponse(opaque)

                buff_size = 0
                if self.flow_control:
                    # set connection buffer size. Considering header size, we roughly
                    # set the total received package size as 10 times as value size.
                    buff_size = self.batch_max_bytes * 10

                opaque=self.r.randint(0, 2**32)
                self.dcp_conn._sendCmd(couchbaseConstants.CMD_DCP_CONTROL,
                                       couchbaseConstants.KEY_DCP_CONNECTION_BUFFER_SIZE,
                                       str(self.batch_max_bytes * 10).encode(), opaque)
                self.dcp_conn._handleSingleResponse(opaque)

                opaque=self.r.randint(0, 2**32)
                self.dcp_conn._sendCmd(couchbaseConstants.CMD_DCP_CONTROL,
                                       couchbaseConstants.KEY_DCP_NOOP, b'true', opaque)
                self.dcp_conn._handleSingleResponse(opaque)

                opaque=self.r.randint(0, 2**32)
                self.dcp_conn._sendCmd(couchbaseConstants.CMD_DCP_CONTROL,
                                       couchbaseConstants.KEY_DCP_NOOP_INTERVAL,
                                       b'180', opaque)
                self.dcp_conn._handleSingleResponse(opaque)
            except EOFError:
                return "error: Fail to set up DCP connection"
            except cb_bin_client.MemcachedError:
                return "error: DCP connect memcached error"
            except socket.error:
                return "error: DCP connection error"
            try:
                opaque=self.r.randint(0, 2**32)
                self.dcp_conn._sendCmd(couchbaseConstants.CMD_DCP_CONTROL,
                                       couchbaseConstants.KEY_DCP_EXT_METADATA,
                                       bool_to_str(True).encode(), opaque)
                self.dcp_conn._handleSingleResponse(opaque)
            except EOFError:
                return "error: Fail to set up DCP connection"
            except cb_bin_client.MemcachedError:
                pass
            except socket.error:
                return "error: DCP connection error"

            self.running = True
            self.start()

            self.add_start_event(self.dcp_conn)
            self.setup_dcp_streams()
        return 0
Exemplo n.º 12
0
            sd = json.loads(source_design)
            if not sd:
                return 0
        except ValueError, e:
            return "error: could not parse source design; exception: %s" % (e)

        err, index_server = pump.filter_server(opts, sink_spec, 'index')
        if err or not index_server:
            logging.error("could not find index server")
            return 0

        spec_parts = pump.parse_spec(opts, sink_spec, 8091)
        if not spec_parts:
            return "error: design sink no spec_parts: " + sink_spec
        host, port, user, pswd, path = spec_parts
        host, port = pump.hostport(index_server)
        sink_bucket = sink_map['buckets'][0]
        url = "/restoreIndexMetadata?bucket=%s" % sink_bucket['name']
        err, conn, response = \
            pump.rest_request(host, couchbaseConstants.INDEX_PORT, user, pswd, opts.ssl,
                              url, method='POST',
                              #body=urllib.urlencode(sd),
                              body=json.dumps(sd),
                              #headers=post_headers,
                              reason='restore index')
        logging.debug(response)
        return 0

    @staticmethod
    def consume_design(opts, sink_spec, sink_map, source_bucket, source_map,
                       source_design):
Exemplo n.º 13
0
    def get_dcp_conn(self):
        """Return previously connected dcp conn."""

        if not self.dcp_conn:
            host, _  = pump.hostport(self.source_node['hostname'])
            port = self.source_node['ports']['direct']
            username = self.opts.username
            password = self.opts.password
            bucket = str(self.source_bucket.get("name"))
            if self.opts.ssl:
                port = couchbaseConstants.SSL_PORT

            logging.debug("  DCPStreamSource connecting mc: " + host + ":" + str(port))

            err, self.dcp_conn = pump.get_mcd_conn(host, port, username, password, bucket)
            if err:
                return err, None

            err, self.mem_conn = pump.get_mcd_conn(host, port, username, password, bucket)
            if err:
                return err, None

            flags = couchbaseConstants.FLAG_DCP_PRODUCER | couchbaseConstants.FLAG_DCP_XATTRS
            extra = struct.pack(couchbaseConstants.DCP_CONNECT_PKT_FMT, 0, flags)
            try:
                opaque=self.r.randint(0, 2**32)
                self.dcp_conn._sendCmd(couchbaseConstants.CMD_DCP_CONNECT, self.dcp_name, \
                                       '', opaque, extra)
                self.dcp_conn._handleSingleResponse(opaque)

                buff_size = 0
                if self.flow_control:
                    # set connection buffer size. Considering header size, we roughly
                    # set the total received package size as 10 times as value size.
                    buff_size = self.batch_max_bytes * 10

                opaque=self.r.randint(0, 2**32)
                self.dcp_conn._sendCmd(couchbaseConstants.CMD_DCP_CONTROL,
                                       couchbaseConstants.KEY_DCP_CONNECTION_BUFFER_SIZE,
                                       str(self.batch_max_bytes * 10), opaque)
                self.dcp_conn._handleSingleResponse(opaque)

                opaque=self.r.randint(0, 2**32)
                self.dcp_conn._sendCmd(couchbaseConstants.CMD_DCP_CONTROL,
                                       couchbaseConstants.KEY_DCP_NOOP,
                                       "true", opaque)
                self.dcp_conn._handleSingleResponse(opaque)

                opaque=self.r.randint(0, 2**32)
                self.dcp_conn._sendCmd(couchbaseConstants.CMD_DCP_CONTROL,
                                       couchbaseConstants.KEY_DCP_NOOP_INTERVAL,
                                       str(180), opaque)
                self.dcp_conn._handleSingleResponse(opaque)
            except EOFError:
                return "error: Fail to set up DCP connection"
            except cb_bin_client.MemcachedError:
                return "error: DCP connect memcached error"
            except socket.error:
                return "error: DCP connection error"
            try:
                opaque=self.r.randint(0, 2**32)
                self.dcp_conn._sendCmd(couchbaseConstants.CMD_DCP_CONTROL,
                                       couchbaseConstants.KEY_DCP_EXT_METADATA,
                                       bool_to_str(True), opaque)
                self.dcp_conn._handleSingleResponse(opaque)
            except EOFError:
                return "error: Fail to set up DCP connection"
            except cb_bin_client.MemcachedError:
                pass
            except socket.error:
                return "error: DCP connection error"

            self.running = True
            self.start()

            self.add_start_event(self.dcp_conn)
            self.setup_dcp_streams()
        return 0
Exemplo n.º 14
0
    def find_conn(self, mconns: Dict[str, cb_bin_client.MemcachedClient], vbucket_id: int, msgs) -> \
            Tuple[couchbaseConstants.PUMP_ERROR, Optional[cb_bin_client.MemcachedClient]]:
        bucket = self.sink_map['buckets'][0]

        vBucketMap = bucket['vBucketServerMap']['vBucketMap']
        serverList = bucket['vBucketServerMap']['serverList']

        if vbucket_id > len(vBucketMap):
            return f'error: map missing vbucket_id: {vbucket_id!s}' \
                f'; perhaps your source does not have vbuckets; if so, try using moxi (HOST:11211) as a destination',\
                   None

        # Primary server for a vbucket_id is the 0'th entry.
        host_port = serverList[vBucketMap[vbucket_id][0]]
        server_host, _ = pump.hostport(host_port)
        if getattr(self, 'alt_add', None):
            host = None
            port = None
            for n in bucket['nodes']:
                if 'alternateAddresses' not in n:
                    # we could raise an error if one of the nodes does not have an alternate address
                    continue

                node_host = '127.0.0.1'
                if 'hostname' in n:
                    node_host, _ = pump.hostport(n['hostname'])

                # if server does not match continue
                if node_host != server_host:
                    continue

                # if correct node check alternate address
                host = n['alternateAddresses']['external']['hostname']
                if self.opts.ssl:
                    if 'kvSSL' in n['alternateAddresses']['external']['ports']:
                        port = n['alternateAddresses']['external']['ports']['kvSSL']
                    else:
                        return 'Host does not have a secure data port', None
                elif 'kv' in n['alternateAddresses']['external']['ports']:
                    port = n['alternateAddresses']['external']['ports']['kv']
                else:
                    return 'Host does not have data service', None
                break

            if host is None or port is None:
                return 'No alternate address information found for host "{}"'.format(host_port), None

            # wrap ipv6 address with []
            if ':' in host and not host.startswith('['):
                host = '[' + host + ']'

            try:
                port_int = int(port)
            except ValueError:
                return 'Invalid port "{}"'.format(port), None

            host_port = host + ":" + str(port)

        logging.debug('Conencting to host "{}" for vbucket {}'.format(host_port, vbucket_id))

        conn = mconns.get(host_port, None)
        if conn is None:
            host, port = pump.hostport(host_port, 11210)
            if self.opts.ssl:
                port = couchbaseConstants.SSL_PORT
            bucket = bucket['name']
            username = self.opts.username
            password = self.opts.password
            if self.opts.username_dest is not None and self.opts.password_dest is not None:
                username = self.opts.username_dest
                password = self.opts.password_dest
            rv, conn = CBSink.connect_mc(host, port, username, password, bucket, self.opts.ssl,
                                         self.opts.no_ssl_verify, self.opts.cacert,
                                         collections=self.opts.collection!=None)
            if rv != 0:
                logging.error(f'error: CBSink.connect() for send: {rv}')
                return rv, None
            if conn is not None:
                mconns[host_port] = conn
                self.add_start_event(conn)
        return 0, conn