问:
How can I add a nested collection to an extension
new to Gradle. I have this simple plugin with an extension that allows me to write custom DSL:

```<code>import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction

apply plugin: NeighborhoodPlugin

class Street {
    String name
    String type

    public Street(name) {
        this.name = name
    }
}

class Neighborhood {
    final NamedDomainObjectContainer<Street> streets
    def name

    public Neighborhood(streets) {
        this.streets = streets
    }

    def streets(Closure closure) {
        streets.configure(closure)
    }
}

// Plugin
class NeighborhoodPlugin implements Plugin<Project> {
    void apply(Project project) {
        // Create the NamedDomainObjectContainers
        def streets = project.container(Street);

        //https://docs.gradle.org/current/dsl/org.gradle.api.plugins.ExtensionAware.html
        def neighborhoodExt = project.extensions.create( 'neighborhood', Neighborhood, streets )
    }
}

neighborhood {
    name = 'My neighborhood'
    streets {
        street1 {
            type = 'T'
        }
        street2 {
            type = 'round'
        }
    }
}

task show {
    doLast {
        println "${neighborhood.name} has ${neighborhood.streets.toArray().length} streets"
    }
}
</code>```

The above seems to work. But I would like to expand on the DSL to add Houses to Streets. Something like this:

```<code>import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction

apply plugin: NeighborhoodPlugin

class House {
    String name
    String address

    public House(name) {
        this.name = name
    }
}

class Street {
    final NamedDomainObjectContainer<House> houses
    String name
    String type

    public Street(name) {
        this.name = name
    }
}

class Neighborhood {
    final NamedDomainObjectContainer<Street> streets
    def name

    public Neighborhood(streets) {
        this.streets = streets
    }

    def streets(Closure closure) {
        streets.configure(closure)
    }
}

// Plugin
class NeighborhoodPlugin implements Plugin<Project> {
    void apply(Project project) {
        // Create the NamedDomainObjectContainers
        def streets = project.container(Street);

        //https://docs.gradle.org/current/dsl/org.gradle.api.plugins.ExtensionAware.html
        def neighborhoodExt = project.extensions.create( 'neighborhood', Neighborhood, streets )
    }
}

neighborhood {
    name = 'My neighborhood'
    streets {
        street1 {
            type = 'T'
            houses {
                blueHouse {
                    address = '100 main'
                }
            }
        }
        street2 {
            type = 'round'
        }
    }
}

task show {
    doLast {
        println "${neighborhood.name} has ${neighborhood.streets.toArray().length} streets"
    }
}
</code>```

I tried different combinations of things but I can never get to it to work. The error is always: No signature of method: build_ch0yxyi3isqke8j97jxnsaw72.neighborhood() is applicable for argument types.

Any help is really appreciated.

答:
This works and I got it from: https://mrhaki.blogspot.com/2016/02/gradle-goodness-using-nested-domain.html:</p>

```<code>import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction

apply plugin: NeighborhoodPlugin

class House {
    String name
    String address

    public House(name) {
        this.name = name
    }
}

class Street {
    NamedDomainObjectContainer<House> houses
    String name
    String type

    public Street(name) {
        this.name = name
    }

    def houses(Closure closure) {
        houses.configure(closure)
    }
}

class Neighborhood {
    final NamedDomainObjectContainer<Street> streets
    def name

    public Neighborhood(streets) {
        this.streets = streets
    }

    def streets(Closure closure) {
        streets.configure(closure)
    }
}

// Plugin
class NeighborhoodPlugin implements Plugin<Project> {
    void apply(Project project) {

        // Create the NamedDomainObjectContainers
        def streets = project.container(Street);

        streets.all {
            houses = project.container(House)
        }

        //https://docs.gradle.org/current/dsl/org.gradle.api.plugins.ExtensionAware.html
        def neighborhoodExt = project.extensions.create( 'neighborhood', Neighborhood, streets )
    }
}

neighborhood {
    name = 'My neighborhood'
    streets {
        main {
            type = 'Cul de-sac'
            houses {
                blueHouse {
                    address = '100 main'
                }
                pinkHouse {
                    address = '101 main'
                }
                greenHouse {
                    address = '103 main'
                }
            }
        }
        round {
            type = 'Round'
            houses {
                yellowHouse {
                    address = '100 round'
                }
                greenHouse {
                    address = '101 round'
                }
            }
        }
    }
}

task show {
    doLast {
        println "${neighborhood.name} has ${neighborhood.streets.toArray().length} streets"
        neighborhood.streets.all {
            println "--> name: ${name}"
            houses.all {
                println "--> --> name: ${name} address: ${address}"
            }
        }
    }
}
</code>```

Body:
new to Gradle. I have this simple plugin with an extension that allows me to write custom DSL:

import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction

apply plugin: NeighborhoodPlugin

class Street {
    String name
    String type

    public Street(name) {
        this.name = name
    }
}

class Neighborhood {
    final NamedDomainObjectContainer<Street> streets
    def name

    public Neighborhood(streets) {
        this.streets = streets
    }

    def streets(Closure closure) {
        streets.configure(closure)
    }
}

// Plugin
class NeighborhoodPlugin implements Plugin<Project> {
    void apply(Project project) {
        // Create the NamedDomainObjectContainers
        def streets = project.container(Street);

        //https://docs.gradle.org/current/dsl/org.gradle.api.plugins.ExtensionAware.html
        def neighborhoodExt = project.extensions.create( 'neighborhood', Neighborhood, streets )
    }
}

neighborhood {
    name = 'My neighborhood'
    streets {
        street1 {
            type = 'T'
        }
        street2 {
            type = 'round'
        }
    }
}

task show {
    doLast {
        println "${neighborhood.name} has ${neighborhood.streets.toArray().length} streets"
    }
}

The above seems to work. But I would like to expand on the DSL to add Houses to Streets. Something like this:

import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction

apply plugin: NeighborhoodPlugin

class House {
    String name
    String address

    public House(name) {
        this.name = name
    }
}

class Street {
    final NamedDomainObjectContainer<House> houses
    String name
    String type

    public Street(name) {
        this.name = name
    }
}

class Neighborhood {
    final NamedDomainObjectContainer<Street> streets
    def name

    public Neighborhood(streets) {
        this.streets = streets
    }

    def streets(Closure closure) {
        streets.configure(closure)
    }
}

// Plugin
class NeighborhoodPlugin implements Plugin<Project> {
    void apply(Project project) {
        // Create the NamedDomainObjectContainers
        def streets = project.container(Street);

        //https://docs.gradle.org/current/dsl/org.gradle.api.plugins.ExtensionAware.html
        def neighborhoodExt = project.extensions.create( 'neighborhood', Neighborhood, streets )
    }
}

neighborhood {
    name = 'My neighborhood'
    streets {
        street1 {
            type = 'T'
            houses {
                blueHouse {
                    address = '100 main'
                }
            }
        }
        street2 {
            type = 'round'
        }
    }
}

task show {
    doLast {
        println "${neighborhood.name} has ${neighborhood.streets.toArray().length} streets"
    }
}

I tried different combinations of things but I can never get to it to work. The error is always: No signature of method: build_ch0yxyi3isqke8j97jxnsaw72.neighborhood() is applicable for argument types.

Any help is really appreciated.

Body:
This works and I got it from: https://mrhaki.blogspot.com/2016/02/gradle-goodness-using-nested-domain.html:

import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction

apply plugin: NeighborhoodPlugin

class House {
    String name
    String address

    public House(name) {
        this.name = name
    }
}

class Street {
    NamedDomainObjectContainer<House> houses
    String name
    String type

    public Street(name) {
        this.name = name
    }

    def houses(Closure closure) {
        houses.configure(closure)
    }
}

class Neighborhood {
    final NamedDomainObjectContainer<Street> streets
    def name

    public Neighborhood(streets) {
        this.streets = streets
    }

    def streets(Closure closure) {
        streets.configure(closure)
    }
}

// Plugin
class NeighborhoodPlugin implements Plugin<Project> {
    void apply(Project project) {

        // Create the NamedDomainObjectContainers
        def streets = project.container(Street);

        streets.all {
            houses = project.container(House)
        }

        //https://docs.gradle.org/current/dsl/org.gradle.api.plugins.ExtensionAware.html
        def neighborhoodExt = project.extensions.create( 'neighborhood', Neighborhood, streets )
    }
}

neighborhood {
    name = 'My neighborhood'
    streets {
        main {
            type = 'Cul de-sac'
            houses {
                blueHouse {
                    address = '100 main'
                }
                pinkHouse {
                    address = '101 main'
                }
                greenHouse {
                    address = '103 main'
                }
            }
        }
        round {
            type = 'Round'
            houses {
                yellowHouse {
                    address = '100 round'
                }
                greenHouse {
                    address = '101 round'
                }
            }
        }
    }
}

task show {
    doLast {
        println "${neighborhood.name} has ${neighborhood.streets.toArray().length} streets"
        neighborhood.streets.all {
            println "--> name: ${name}"
            houses.all {
                println "--> --> name: ${name} address: ${address}"
            }
        }
    }
}


来源: stackexchange

问:
Stream live audio to Node.js server
I'm working on a project and I require to send an audio stream to a Node.js server. I'm able to capture microphone sound with this function:

```<code>function micCapture(){
    'use strict';

    navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

    var constraints = {
        audio: true,
        video: false
    };

    var video = document.querySelector('video');

    function successCallback(stream) {
        window.stream = stream; // stream available to console
        if (window.URL) {
            video.src = window.webkitURL.createObjectURL(stream);
        } else {
            video.src = stream;
        }
        //Send audio stream
        //server.send(stream);
    }

    function errorCallback(error) {
        console.log('navigator.getUserMedia error: ', error);
    }

    navigator.getUserMedia(constraints, successCallback, errorCallback);
}
</code>```

As you can see, I'm able to capture audio and play it on the website.

Now I want to send that audio stream to a Node.js server, and send it back to other clients. Like a voicechat, but I don't want to use WebRTC as I need the stream in the server. How can I achieve this? Can I use socket.io-stream to do this? In the examples I saw, they recorded the audio, and sent a file, but I need "live" audio.

答:
I have recently done live audio upload using socket.io from browser to server. I am going to answer here in case someone else needs it.

```<code>    var stream;
    var socket = io();
    var bufferSize = 1024 * 16;
    var audioContext = new AudioContext();
    // createScriptProcessor is deprecated. Let me know if anyone find alternative
    var processor = audioContext.createScriptProcessor(bufferSize, 1, 1);
    processor.connect(audioContext.destination);

    navigator.mediaDevices.getUserMedia({ video: false, audio: true }).then(handleMicStream).catch(err => {
      console.log('error from getUserMedia', err);
    });

</code>```

handleMicStream will run when user accepts the permission to use microphone.

```<code>  function handleMicStream(streamObj) {
    // keep the context in a global variable
    stream = streamObj;

    input = audioContext.createMediaStreamSource(stream);

    input.connect(processor);

    processor.onaudioprocess = e => {
      microphoneProcess(e); // receives data from microphone
    };
  }

  function microphoneProcess(e) {
    const left = e.inputBuffer.getChannelData(0); // get only one audio channel
    const left16 = convertFloat32ToInt16(left); // skip if you don't need this
    socket.emit('micBinaryStream', left16); // send to server via web socket
  }

// Converts data to BINARY16
function convertFloat32ToInt16(buffer) {
    let l = buffer.length;
    const buf = new Int16Array(l / 3);

    while (l--) {
      if (l % 3 === 0) {
        buf[l / 3] = buffer[l] * 0xFFFF;
      }
    }
    return buf.buffer;
  }

</code>```

Have your socket.io server listen to micBinaryStream and you should get the data. I needed the data as a BINARY16 format for google api if you do not need this you can skip the function call to convertFloat32ToInt16().

Important

When you need to stop listening you MUST disconnect the the processor and end the stream. Run the function closeAll() below.

```<code>function closeAll() {
    const tracks = stream ? stream.getTracks() : null;
    const track = tracks ? tracks[0] : null;

    if (track) {
      track.stop();
    }

    if (processor) {
      if (input) {
        try {
          input.disconnect(processor);
        } catch (error) {
          console.warn('Attempt to disconnect input failed.');
        }
      }
      processor.disconnect(audioContext.destination);
    }

    if (audioContext) {
      audioContext.close().then(() => {
        input = null;
        processor = null;
        audioContext = null;
      });
    }
  }

</code>```

ContentLicense: CC BY-SA 3.0

Title: Stream live audio to Node.js server

Body:
I'm working on a project and I require to send an audio stream to a Node.js server. I'm able to capture microphone sound with this function:

function micCapture(){
    'use strict';

    navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

    var constraints = {
        audio: true,
        video: false
    };

    var video = document.querySelector('video');

    function successCallback(stream) {
        window.stream = stream; // stream available to console
        if (window.URL) {
            video.src = window.webkitURL.createObjectURL(stream);
        } else {
            video.src = stream;
        }
        //Send audio stream
        //server.send(stream);
    }

    function errorCallback(error) {
        console.log('navigator.getUserMedia error: ', error);
    }

    navigator.getUserMedia(constraints, successCallback, errorCallback);
}

As you can see, I'm able to capture audio and play it on the website.

Now I want to send that audio stream to a Node.js server, and send it back to other clients. Like a voicechat, but I don't want to use WebRTC as I need the stream in the server. How can I achieve this? Can I use socket.io-stream to do this? In the examples I saw, they recorded the audio, and sent a file, but I need "live" audio.

Body:
I have recently done live audio upload using socket.io from browser to server. I am going to answer here in case someone else needs it.

    var stream;
    var socket = io();
    var bufferSize = 1024 * 16;
    var audioContext = new AudioContext();
    // createScriptProcessor is deprecated. Let me know if anyone find alternative
    var processor = audioContext.createScriptProcessor(bufferSize, 1, 1);
    processor.connect(audioContext.destination);

    navigator.mediaDevices.getUserMedia({ video: false, audio: true }).then(handleMicStream).catch(err => {
      console.log('error from getUserMedia', err);
    });

handleMicStream will run when user accepts the permission to use microphone.

  function handleMicStream(streamObj) {
    // keep the context in a global variable
    stream = streamObj;

    input = audioContext.createMediaStreamSource(stream);

    input.connect(processor);

    processor.onaudioprocess = e => {
      microphoneProcess(e); // receives data from microphone
    };
  }

  function microphoneProcess(e) {
    const left = e.inputBuffer.getChannelData(0); // get only one audio channel
    const left16 = convertFloat32ToInt16(left); // skip if you don't need this
    socket.emit('micBinaryStream', left16); // send to server via web socket
  }

// Converts data to BINARY16
function convertFloat32ToInt16(buffer) {
    let l = buffer.length;
    const buf = new Int16Array(l / 3);

    while (l--) {
      if (l % 3 === 0) {
        buf[l / 3] = buffer[l] * 0xFFFF;
      }
    }
    return buf.buffer;
  }

Have your socket.io server listen to micBinaryStream and you should get the data. I needed the data as a BINARY16 format for google api if you do not need this you can skip the function call to convertFloat32ToInt16().

Important

When you need to stop listening you MUST disconnect the the processor and end the stream. Run the function closeAll() below.

function closeAll() {
    const tracks = stream ? stream.getTracks() : null;
    const track = tracks ? tracks[0] : null;

    if (track) {
      track.stop();
    }

    if (processor) {
      if (input) {
        try {
          input.disconnect(processor);
        } catch (error) {
          console.warn('Attempt to disconnect input failed.');
        }
      }
      processor.disconnect(audioContext.destination);
    }

    if (audioContext) {
      audioContext.close().then(() => {
        input = null;
        processor = null;
        audioContext = null;
      });
    }
  }

ContentLicense: CC BY-SA 4.0


问:
How to enable Cloudwatch logging for AWS API GW via Cloudformation template
I am trying to enable cloudwatch logs for AWS API Gateway via cloudformation template but it does not enables. I have tried setting up logginglevel to INFO in both Stage description and also Method settings. Any idea on what am I missing?

When I manually enable logging through UI, it works. Not working when I try to enable through cloudformation template as below -

Note: I am just using plain cloudformation template and I have already added role ARN that has permissions to API Gateway in my account to log cloudwatch

```<code>TestDeployment:
  Type: AWS::ApiGateway::Deployment
  Properties:
    Description: API Deployment
    RestApiId: testApi
    StageName: 'dev'
    StageDescription:
      Description: Stage - DEV
      LoggingLevel: INFO
      MethodSettings:
        - ResourcePath: "/testresource"
          HttpMethod: "POST"
          LoggingLevel: INFO
</code>```

答:
Have you already configure API Gateway RestApi to write logs into CloudWatch as describe in AWS documentation : https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-logging.html

Note that you must set permissions for CloudWatch logging.

Body:
I am trying to enable cloudwatch logs for AWS API Gateway via cloudformation template but it does not enables. I have tried setting up logginglevel to INFO in both Stage description and also Method settings. Any idea on what am I missing?

When I manually enable logging through UI, it works. Not working when I try to enable through cloudformation template as below -

Note: I am just using plain cloudformation template and I have already added role ARN that has permissions to API Gateway in my account to log cloudwatch

TestDeployment:
  Type: AWS::ApiGateway::Deployment
  Properties:
    Description: API Deployment
    RestApiId: testApi
    StageName: 'dev'
    StageDescription:
      Description: Stage - DEV
      LoggingLevel: INFO
      MethodSettings:
        - ResourcePath: "/testresource"
          HttpMethod: "POST"
          LoggingLevel: INFO


问:
Splitting a string using a next line regex followed by a digit (JAVA)
I have the following string which I need to split on space, commas, and next line character.
Sample string: "./homework2 3,phone3,desc3,brand4\n4,phone4,desc4,brand4\n5,phone5,desc5,brand5"

I am using split function as: .split("[,\\s+\\n+]"); but I am unable to get the required out put. The program keeps reading brand4\n4 as one substring.

Help would be appreciated.

答:
Instead of using \s+ and \n+ you could use a common quantifier. The below depicts the same

```<code>String s = "./homework2 3,phone3,desc3,brand4\n4,phone4,desc4,brand4\n5,phone5,desc5,brand5";
String[]s1 = s.split("[,\\s\\n]+");
for(String s2:s1) {
    System.out.println(s2);
}
</code>```

As it leads to

```<code>./homework2
3
phone3
desc3
brand4
4
phone4
desc4
brand4
5
phone5
desc5
brand5
</code>```

Body:
Instead of using \s+ and \n+ you could use a common quantifier. The below depicts the same

String s = "./homework2 3,phone3,desc3,brand4\n4,phone4,desc4,brand4\n5,phone5,desc5,brand5";
String[]s1 = s.split("[,\\s\\n]+");
for(String s2:s1) {
    System.out.println(s2);
}

As it leads to

./homework2
3
phone3
desc3
brand4
4
phone4
desc4
brand4
5
phone5
desc5
brand5


问:
Can't find ~/.vim/bundle directory on Mac
I am trying to install YouCompleteMe on Mac and following the procedure, I am not able to locate ~/.vim/bundle. I can locate .vim in my home folder but there is no directory bundle inside it.

I am following this link https://github.com/ycm-core/YouCompleteMe/blob/master/README.md#installation to install YouCompleteMe.

答: if it doesn't exists it is safe to create it</p>


答:
If you have only 2 warehouse  in sql you could try  </p>

```<code>select distinct item_id, t1._qty qty_warehouse1, t2.qty qty_warehouse1
from my_table m
left  join  (
    select item_id, qty
    from my_table
    where warehouse_id = 1
) t1 on t1.item_id = m.item_id
left  join  (
    select item_id, qty
    from my_table
    where warehouse_id = 2
) t2 on t2.item_id = m.item_id
</code>```

Title: How to select statement for showing data

Body:
i have table in mysql like this

-----------------------------
|id|warehouse_id|item_id|qty|
---|------------|-------|---|
|1 | 1          | 1     |10 |
|2 | 1          | 2     |23 |
|3 | 2          | 1     |45 |
|4 | 2          | 2     |66 |
|5 | 1          | 3     |44 |

How using select statement to show table what i want like this

------------------------------------------
|id|item_id|qty warehouse 1|qty warehouse 2
---|-------|---------------|-------------
|1 | 1     | 10            |45         |
|2 | 2     | 23            |66         |
|3 | 3     | 44            |0          |

i was trying using eloquent laravel like this

ItemStockModel::get()

thank you

Body:
If you have only 2 warehouse  in sql you could try

select distinct item_id, t1._qty qty_warehouse1, t2.qty qty_warehouse1
from my_table m
left  join  (
    select item_id, qty
    from my_table
    where warehouse_id = 1
) t1 on t1.item_id = m.item_id
left  join  (
    select item_id, qty
    from my_table
    where warehouse_id = 2
) t2 on t2.item_id = m.item_id


问:
name 'delta_scroll' is not defined even though I defined it?
so I am trying to make my enemy not scroll with my camera when it moves left and right

I someone helped me make a function to stop my enemy from scrolling all it suppose to do is not make my enemy scroll example vid

```<code>def onscroll(enemying, delta_scroll):
    for enemys in enemying:
        enemys.position = (enemys.position[0] - delta_scroll, enemys.position[1])

</code>```

then on my main loop I called that function so my enemy doesnt scroll with my screen

```<code>
    # camera left and right movement
    if playerman.y < 250:
        playerman.y += 1
        for enemys in enemying:
            enemys.y += delta_scroll

</code>```

but for some reason I keep getting the same error

```<code>
name 'delta_scroll' is not defined

</code>```

Enemy Class

my full code

答:
Quick tip- there are a TON of pg.image.load("myImg.png") commands. here is a better way of doing it:

```<code>standingright = []
for i in range(1, 16):
    imgPath = "d"+str(i)+".png"
    img = pg.image.load(imgPath)
    standingright.append(img)
</code>```

This is a much more concise way of loading the images. It will result in the exact same list of images in the exact same order, but I thought I would mention it to you because it will make your code much neater.

About the issue at hand: I searched your code for mentions of delta_scroll, and found it being used, but never defined. Also I saw you defined the function "onscroll", but never used it. Are you getting these two mixed up perhaps?

Body:
so I am trying to make my enemy not scroll with my camera when it moves left and right

I someone helped me make a function to stop my enemy from scrolling all it suppose to do is not make my enemy scroll example vid

def onscroll(enemying, delta_scroll):
    for enemys in enemying:
        enemys.position = (enemys.position[0] - delta_scroll, enemys.position[1])

then on my main loop I called that function so my enemy doesnt scroll with my screen

    # camera left and right movement
    if playerman.y < 250:
        playerman.y += 1
        for enemys in enemying:
            enemys.y += delta_scroll

but for some reason I keep getting the same error

name 'delta_scroll' is not defined

Enemy Class

my full code

Body:
Quick tip- there are a TON of pg.image.load("myImg.png") commands. here is a better way of doing it:

standingright = []
for i in range(1, 16):
    imgPath = "d"+str(i)+".png"
    img = pg.image.load(imgPath)
    standingright.append(img)

This is a much more concise way of loading the images. It will result in the exact same list of images in the exact same order, but I thought I would mention it to you because it will make your code much neater.

About the issue at hand: I searched your code for mentions of delta_scroll, and found it being used, but never defined. Also I saw you defined the function "onscroll", but never used it. Are you getting these two mixed up perhaps?


问:
How to make setState take effect immediately?
There is an input element in my code:

```<code><input id="input" className="ml-2" type="number" name="Qty" min="1" max="999" value={qty} onChange={(e) => {changeQty(e)}}/>
</code>```

And the onChange handler is:

```<code>    const changeQty = (e) => {
        setQty(e.target.value);
        console.log(qty);
    }
</code>```

So I suppose that whatever I enter in the input field will be printed out in the console, but the fact is there is delay.

For example, the default value is 1, then I type 2, then 1 will be printed out. Then I type 3, then 2 will be printed out. The number printed out is the previous one I entered instead of the current one, as shown below:

Could anyone tell me how to remove the delay?

I read useState set method not reflecting change immediately, but still cannot solve it.

I tried the code below as the answer indicates,

```<code>useEffect(() => {
    setQty(document.getElementById("input").value)
}, [qty]);
</code>```

but an error ReferenceError: Cannot access 'qty' before initialization occurred.

Thanks!

答:
Since you didn't share all of your code, it's difficult to answer your question exactly, but it looks like you're using React's hooks, so I've created an example that uses hooks correctly to set the qty state and log the current qty value.

const Quantity = function() {
  const [qty, setQty] = React.useState(0);
  const changeQty = (e) => {
    setQty(e.target.value);
  };
  React.useEffect(() => {
    console.log(qty);
  }, [qty]);

  return (
      <input id="input" className="ml-2" type="number" name="Qty" min="1" max="999" value={qty} onChange={(e) => {changeQty(e)}}/>
  );
};
ReactDOM.render(<Quantity />, document.getElementById("app_root"));```
<pre class="snippet-code-html lang-html prettyprint-override"><code><head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.25/browser-polyfill.min.js"></script>
</head>

<body>
  <div id="app_root"></div>
</body></code>```

Body:
There is an input element in my code:

<input id="input" className="ml-2" type="number" name="Qty" min="1" max="999" value={qty} onChange={(e) => {changeQty(e)}}/>

And the onChange handler is:

    const changeQty = (e) => {
        setQty(e.target.value);
        console.log(qty);
    }

So I suppose that whatever I enter in the input field will be printed out in the console, but the fact is there is delay.

For example, the default value is 1, then I type 2, then 1 will be printed out. Then I type 3, then 2 will be printed out. The number printed out is the previous one I entered instead of the current one, as shown below:

Could anyone tell me how to remove the delay?

I read useState set method not reflecting change immediately, but still cannot solve it.

I tried the code below as the answer indicates,

useEffect(() => {
    setQty(document.getElementById("input").value)
}, [qty]);

but an error ReferenceError: Cannot access 'qty' before initialization occurred.

Thanks!

Body:
Since you didn't share all of your code, it's difficult to answer your question exactly, but it looks like you're using React's hooks, so I've created an example that uses hooks correctly to set the qty state and log the current qty value.

const Quantity = function() {
  const [qty, setQty] = React.useState(0);
  const changeQty = (e) => {
    setQty(e.target.value);
  };
  React.useEffect(() => {
    console.log(qty);
  }, [qty]);

  return (
      <input id="input" className="ml-2" type="number" name="Qty" min="1" max="999" value={qty} onChange={(e) => {changeQty(e)}}/>
  );
};
ReactDOM.render(<Quantity />, document.getElementById("app_root"));

<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.25/browser-polyfill.min.js"></script>
</head>

<body>
  <div id="app_root"></div>
</body>


问:
Problem accessing dockerized node application from outside of container
i have been trying to dockerize an angular project, using Docker Desktop for windows, with linux containers, and Hyper-V.

Here is my dockerfile:

```<code>FROM node:alpine

WORKDIR /var/app

EXPOSE 4200

COPY package*.json ./
COPY proxy*.json ./

COPY . .
RUN npm install @angular/cli -g
#Custom dependencies
RUN npm config set registry http://maven.corp.com.br:8081/artifactory/api/npm/
RUN npm install

RUN npm run build:dev

ENTRYPOINT npm start
</code>```

i build it and can run it just fine with:

```<code>docker build -t name .

docker run -p 4200:4200 name
</code>```

The problem is, when i try to access https://localhost:4200 from my windows pc, i get ERR_CONNECTION_CLOSED.

However, if i go into the container cli, and use Links (the command line web browser https://i.imgur.com/jwhD9cm.gif) to access the url, it works just fine, i'm just having issues trying to access it from my windows pc.

I tried using the host.docker.domain dns aswell but no success.

Any help will be greatly appreciated.

Thanks!

答: Thank you very much @paltaa , all i had to do was change from "npm start" to a custom "ng serve" with the flag --host 0.0.0.0"</p>

Body:
i have been trying to dockerize an angular project, using Docker Desktop for windows, with linux containers, and Hyper-V.

Here is my dockerfile:

FROM node:alpine

WORKDIR /var/app

EXPOSE 4200

COPY package*.json ./
COPY proxy*.json ./

COPY . .
RUN npm install @angular/cli -g
#Custom dependencies
RUN npm config set registry http://maven.corp.com.br:8081/artifactory/api/npm/
RUN npm install

RUN npm run build:dev

ENTRYPOINT npm start

i build it and can run it just fine with:

docker build -t name .

docker run -p 4200:4200 name

The problem is, when i try to access https://localhost:4200 from my windows pc, i get ERR_CONNECTION_CLOSED.

However, if i go into the container cli, and use Links (the command line web browser https://i.imgur.com/jwhD9cm.gif) to access the url, it works just fine, i'm just having issues trying to access it from my windows pc.

I tried using the host.docker.domain dns aswell but no success.

Any help will be greatly appreciated.

Thanks!


问:
c# datatable Cannot update. Database or object is read-only
```<code>private void Form1_Load(object sender, EventArgs e)
        {
            GetDataTable(@"C:\Documents and Settings\agordon\Desktop\ACTIVITYEX.log");
        }
        public System.Data.DataTable GetDataTable(string strFileName)
        {
            System.Data.OleDb.OleDbConnection conn =
                new System.Data.OleDb.OleDbConnection
                    ("Provider=Microsoft.Jet.OleDb.4.0; Data Source = "
                    + System.IO.Path.GetDirectoryName(strFileName)
                    + ";Extended Properties = \"Text;HDR=YES;FMT=TabDelimited\"");
            conn.Open();
            string strQuery = "SELECT * FROM [" + System.IO.Path.GetFileName(strFileName) + "]";
            System.Data.OleDb.OleDbDataAdapter adapter = new System.Data.OleDb.OleDbDataAdapter(strQuery, conn);
            System.Data.DataTable ds = new System.Data.DataTable("CSV File");
            adapter.Fill(ds);
            return ds;
        }
</code>```

when THE SAME file is named .csv it does not give me an error; however when i rename it to .log it says Cannot update.  Database or object is read-only. on adapter.Fill

is this a compiler error?

答: No, it's a not a compiler error. If anything it's an error from the OleDb Jet engine. I have ran into enough problems with Jet in the past so I usually avoid it. You might save yourself lots of debugging time by using TextFieldParser.</p>

Body:
private void Form1_Load(object sender, EventArgs e)
        {
            GetDataTable(@"C:\Documents and Settings\agordon\Desktop\ACTIVITYEX.log");
        }
        public System.Data.DataTable GetDataTable(string strFileName)
        {
            System.Data.OleDb.OleDbConnection conn =
                new System.Data.OleDb.OleDbConnection
                    ("Provider=Microsoft.Jet.OleDb.4.0; Data Source = "
                    + System.IO.Path.GetDirectoryName(strFileName)
                    + ";Extended Properties = \"Text;HDR=YES;FMT=TabDelimited\"");
            conn.Open();
            string strQuery = "SELECT * FROM [" + System.IO.Path.GetFileName(strFileName) + "]";
            System.Data.OleDb.OleDbDataAdapter adapter = new System.Data.OleDb.OleDbDataAdapter(strQuery, conn);
            System.Data.DataTable ds = new System.Data.DataTable("CSV File");
            adapter.Fill(ds);
            return ds;
        }

when THE SAME file is named .csv it does not give me an error; however when i rename it to .log it says Cannot update.  Database or object is read-only. on adapter.Fill

is this a compiler error?


问:
Commiter email address does not match in IntelliJ even changing it to correct one
When I try to push my commits from git repository to gerrit remote repository from Linux environment in IntelliJ idea I get the following error:

```<code>remote: ERROR:  committer email address ***** [K
remote: ERROR:  does not match your user account.[K
</code>```

Even if I changed the settings to the correct ones for git and gerrit (I can see that at: git config -l from console), it still picks the old "wrong" email.

What could be wrong?

答:
I experienced the same error when our corporate  email address changed and for me was easily fixed with :

```<code>#!/bin/sh

git filter-branch --env-filter '

OLD_EMAIL="your-old-email@example.com"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="your-correct-email@example.com"

if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
export GIT_COMMITTER_NAME="$CORRECT_NAME"
export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
export GIT_AUTHOR_NAME="$CORRECT_NAME"
export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags
</code>```

Run in the root of the git repo.

Based on :
https://help.github.com/en/github/using-git/changing-author-info

I also edited the repo's .git/config to add the user stanza :

```<code>[user]
  name = Your Correct Name
  email = your-correct-email@example.com
</code>```

Then

```<code>git commit --amend --reset-author
git push
</code>```

PS: This is on a Gerrit Server

Body:
When I try to push my commits from git repository to gerrit remote repository from Linux environment in IntelliJ idea I get the following error:

remote: ERROR:  committer email address ***** [K
remote: ERROR:  does not match your user account.[K

Even if I changed the settings to the correct ones for git and gerrit (I can see that at: git config -l from console), it still picks the old "wrong" email.

What could be wrong?

Body:
I experienced the same error when our corporate  email address changed and for me was easily fixed with :

#!/bin/sh

git filter-branch --env-filter '

OLD_EMAIL="your-old-email@example.com"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="your-correct-email@example.com"

if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
export GIT_COMMITTER_NAME="$CORRECT_NAME"
export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
export GIT_AUTHOR_NAME="$CORRECT_NAME"
export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags

Run in the root of the git repo.

Based on :
https://help.github.com/en/github/using-git/changing-author-info

I also edited the repo's .git/config to add the user stanza :

[user]
  name = Your Correct Name
  email = your-correct-email@example.com

Then

git commit --amend --reset-author
git push

PS: This is on a Gerrit Server


问:
Change width of tk Combobox dropdown scrollbar
Is it possible to change the width of a tk Combobox scrolldown bar in python 2.7? I'm not talking about the combobox width, but rather the scrollbar width on the combobox that appears when the combobox is active.  For example:</p>

```<code>self.cmbSortOrder=ttk.Combobox(self.frame2, value=l, textvariable=self.SortOrder)
self.cmbSortOrder.bind("<<ComboboxSelected>>", self.reloadList)
self.cmbSortOrder.pack(side=LEFT)
</code>```

答:
The Combobox widget leverages the Scrollbar widget, thus changing the style of the Scrollbar widget will be observable by instances of the Combobox widget. A crude example below shows this:</p>

```<code># Create a style instance
style = ttk.Style()

# Specify style the preference(s) for combo box widgets
style.configure( 'TCombobox', arrowsize=25 )

# Alter the template properties of the scroll bar to affect the Combobox widget
style.configure( 'Vertical.TScrollbar', width=22 )
style.configure( 'Vertical.TScrollbar', arrowsize =22 )
style.configure( 'Vertical.TScrollbar', arrowsize =22 )
</code>```

Body:
Is it possible to change the width of a tk Combobox scrolldown bar in python 2.7? I'm not talking about the combobox width, but rather the scrollbar width on the combobox that appears when the combobox is active.  For example:

self.cmbSortOrder=ttk.Combobox(self.frame2, value=l, textvariable=self.SortOrder)
self.cmbSortOrder.bind("<<ComboboxSelected>>", self.reloadList)
self.cmbSortOrder.pack(side=LEFT)

Body:
The Combobox widget leverages the Scrollbar widget, thus changing the style of the Scrollbar widget will be observable by instances of the Combobox widget. A crude example below shows this:

# Create a style instance
style = ttk.Style()

# Specify style the preference(s) for combo box widgets
style.configure( 'TCombobox', arrowsize=25 )

# Alter the template properties of the scroll bar to affect the Combobox widget
style.configure( 'Vertical.TScrollbar', width=22 )
style.configure( 'Vertical.TScrollbar', arrowsize =22 )
style.configure( 'Vertical.TScrollbar', arrowsize =22 )


问:
Android Studio: java.util.NoSuchElementException: No line found
I am trying to run the following code in Android Studio and getting the shown error. Actually, whenever I use scanner.nextLine(), I get a similar error.

```<code>    package com.example.javalib;

    import java.util.Scanner;

    public class ChallengeThirteen {

        public static void main(String[] args)  {

            Scanner scanner = new Scanner(System.in);

            System.out.println("Enter your name: ");
            String name = scanner.nextLine();

            System.out.println("Your name is "+ name);

        }
    }
</code>```

Error:

```<code>> Task :JavaLib:ChallengeThirteen.main() FAILED
Enter your name:
Exception in thread "main" java.util.NoSuchElementException: No line found
  at java.util.Scanner.nextLine(Scanner.java:1540)
  at com.example.javalib.ChallengeThirteen.main(ChallengeThirteen.java:12)

Execution failed for task ':JavaLib:ChallengeThirteen.main()'.
> Process 'command '/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java'' finished with
</code>```

non-zero exit value 1

答: Your problem is that you're using Android Studio. Android Studio is specifically designed to write applications for Android, and is not designed to be able to create standalone java applications. I would recommend using IntelliJ IDEA instead of Android Studio as its interface is practically identical and it supports standalone applications. You will also get a command line when you run a program, which will let you use the System.in input stream and will get rid of this error entirely. This error occured because Android Studio does not let you use the System.in input stream from the command line by default, which means it will not detect a line for the Scanner object.</p>

Body:
I am trying to run the following code in Android Studio and getting the shown error. Actually, whenever I use scanner.nextLine(), I get a similar error.

    package com.example.javalib;

    import java.util.Scanner;

    public class ChallengeThirteen {

        public static void main(String[] args)  {

            Scanner scanner = new Scanner(System.in);

            System.out.println("Enter your name: ");
            String name = scanner.nextLine();

            System.out.println("Your name is "+ name);

        }
    }

Error:

> Task :JavaLib:ChallengeThirteen.main() FAILED
Enter your name:
Exception in thread "main" java.util.NoSuchElementException: No line found
  at java.util.Scanner.nextLine(Scanner.java:1540)
  at com.example.javalib.ChallengeThirteen.main(ChallengeThirteen.java:12)

Execution failed for task ':JavaLib:ChallengeThirteen.main()'.
> Process 'command '/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java'' finished with

non-zero exit value 1


问:
Delete Operation Slows down intermittently oracle 11g
We have a audit Table in production environment where we delete almost 15 millions data everyday(data which is older than some days)in PL/SQL batch. On a good day this query takes 1.5 hours to delete the same data. But intermittently some days this is not deleting the same amount of data even in 4 hours. There is no trigger on this table and Created column is indexed.

```<code>DELETE FROM SIEBEL.CX_AUDIT_SEARCH
WHERE CREATED < '20-MAy-2020' AND rownum <= 10000;
</code>```

Explain pla:

```<code>DELETE STATEMENT    ALL_ROWS    6   10000   180000
DELETE SIEBEL.CX_AUDIT_SEARCH
COUNT(STOPKEY)                                  ROWNUM<=10000
INDEX(RANGE SCAN) SIEBEL.CX_AUDIT_SEARCH_U1 ANALYZED    6   170692  3072456             "CREATED"<'20-MAy-2020'
</code>```

Could you please suggest any possible reason.

答:
It’s obvious that this is a very busy table. 15M rows/day means about 10416 rows/minute, which means that at the time you are deleting these rows, thousands of records are being inserted. While Oracle tries to delete the old rows, and update the CREATED index, more rows are inserted and committed.

I see you are trying to DELETE 10000 rows at a time. I assume you commit after these 10000 rows, so the following approach may be a bit faster because the SELECT is running only once and you don't rescan 1500 times the busy table...

```<code>declare
cursor c_rowids is
  SELECT T.ROWID
      FROM SIEBEL.CX_AUDIT_SEARCH T
     WHERE CREATED < '20-MAy-2020';
type t_tbl_rowids is table of rowid;
tbl_rowids t_tbl_rowids;
begin
  open c_rowids;
  Loop
    fetch c_rowids bulk collect into tbl_rowids limit 10000;
    exit when tbl_rowids.count = 0;
    forall i in 1..tbl_rowids.count
      DELETE FROM SIEBEL.CX_AUDIT_SEARCH
        WHERE ROWID = tbl_rowids(i);

    COMMIT;
  End loop;
  close c_rowids;
end;
</code>```

Body:
We have a audit Table in production environment where we delete almost 15 millions data everyday(data which is older than some days)in PL/SQL batch. On a good day this query takes 1.5 hours to delete the same data. But intermittently some days this is not deleting the same amount of data even in 4 hours. There is no trigger on this table and Created column is indexed.

DELETE FROM SIEBEL.CX_AUDIT_SEARCH
WHERE CREATED < '20-MAy-2020' AND rownum <= 10000;

Explain pla:

DELETE STATEMENT    ALL_ROWS    6   10000   180000
DELETE SIEBEL.CX_AUDIT_SEARCH
COUNT(STOPKEY)                                  ROWNUM<=10000
INDEX(RANGE SCAN) SIEBEL.CX_AUDIT_SEARCH_U1 ANALYZED    6   170692  3072456             "CREATED"<'20-MAy-2020'

Could you please suggest any possible reason.

Body:
It’s obvious that this is a very busy table. 15M rows/day means about 10416 rows/minute, which means that at the time you are deleting these rows, thousands of records are being inserted. While Oracle tries to delete the old rows, and update the CREATED index, more rows are inserted and committed.

I see you are trying to DELETE 10000 rows at a time. I assume you commit after these 10000 rows, so the following approach may be a bit faster because the SELECT is running only once and you don't rescan 1500 times the busy table...

declare
cursor c_rowids is
  SELECT T.ROWID
      FROM SIEBEL.CX_AUDIT_SEARCH T
     WHERE CREATED < '20-MAy-2020';
type t_tbl_rowids is table of rowid;
tbl_rowids t_tbl_rowids;
begin
  open c_rowids;
  Loop
    fetch c_rowids bulk collect into tbl_rowids limit 10000;
    exit when tbl_rowids.count = 0;
    forall i in 1..tbl_rowids.count
      DELETE FROM SIEBEL.CX_AUDIT_SEARCH
        WHERE ROWID = tbl_rowids(i);

    COMMIT;
  End loop;
  close c_rowids;
end;


问:
Dynamically cast to a proper subclass from parent class in a method
I have a Java interface PlatformConfigurable. I also have two classes PlatformProducerConfig and PlatformConsumerConfig.

Later on, I need to add a common config to both that sets a property to an empty string:

```<code>    private PlatformConfigurable disableHostNameVerificationConfig(PlatformConfigurable platformConfig) {
        if (platformConfig instanceof PlatformProducerConfig) {
            PlatformProducerConfig oldConfig = (PlatformProducerConfig) platformConfig;
            Map<String, String> additionalConfig = oldConfig.additionalProperties();
            Map<String, String> newConfig = new HashMap<>(Optional.ofNullable(additionalConfig).orElseGet(ImmutableMap::of));
            newConfig.put(SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, "");
            return oldConfig.toBuilder().additionalProperties(newConfig).build();
        }
        else if (platformConfig instanceof PlatformConsumerConfig) {
            PlatformConsumerConfig oldConfig = (PlatformConsumerConfig) platformConfig;
            Map<String, String> additionalConfig = platformConfig.additionalProperties();
            Map<String, String> newConfig = new HashMap<>(Optional.ofNullable(additionalConfig).orElseGet(ImmutableMap::of));
            newConfig.put(SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, "");
            return oldConfig.toBuilder().additionalProperties(newConfig).build();
        }
        return platformConfig;
    }
</code>```

I am casting to producer or consumer config because the PlatformConfigurable interface doesn't have .toBuilder() or .build() methods declared in it, and I don't have access to modify the interface, as I can only implement it.

I would want to get rid of the duplicate code:

```<code>Map<String, String> additionalConfig = platformConfig.additionalProperties();
            Map<String, String> newConfig = new HashMap<>(Optional.ofNullable(additionalConfig).orElseGet(ImmutableMap::of));
            newConfig.put(SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, "");
            return oldConfig.toBuilder().additionalProperties(newConfig).build();
</code>```

I was thinking of using lambdas, but I am not 100% sure how to do it.

答:
Adding one thing in Alex Rudenko's answer, and making different function to add different implementations of interfaces.

private PlatformConfigurable disableHostNameVerificationConfig(PlatformConfigurable platformConfig) {
    if ((platformConfig == null)) {
        return platformConfig;
    }

    Map<String, String> additionalConfig = platformConfig.additionalProperties();
    Map<String, String> newConfig = new HashMap<>(Optional.ofNullable(additionalConfig).orElseGet(ImmutableMap::of));
    newConfig.put(SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, "");
    return PlatformConfigurableObject(platformConfig, newConfig);
}

```

<p>So you can handle all instances in a different method, and whenever PlatfromXCofing classes are added later you only have to change this method. Single Responsibility Principle.  </p>

<pre class="lang-java prettyprint-override"><code>private PlatformConfigurable PlatformConfigurableObject(PlatformConfigurable platformConfig, Map<String, String> newConfig){
    if (platformConfig instanceof PlatformProducerConfig) {
        return ((PlatformProducerConfig)platformConfig).toBuilder().additionalProperties(newConfig).build();
    } else if (platformConfig instanceof PlatformConsumerConfig){
        return ((PlatformConsumerConfig)platformConfig).toBuilder().additionalProperties(newConfig).build();
    } else{
    return platformConfig;
    }
}

</code>```

Body:
I have a Java interface PlatformConfigurable. I also have two classes PlatformProducerConfig and PlatformConsumerConfig.

Later on, I need to add a common config to both that sets a property to an empty string:

    private PlatformConfigurable disableHostNameVerificationConfig(PlatformConfigurable platformConfig) {
        if (platformConfig instanceof PlatformProducerConfig) {
            PlatformProducerConfig oldConfig = (PlatformProducerConfig) platformConfig;
            Map<String, String> additionalConfig = oldConfig.additionalProperties();
            Map<String, String> newConfig = new HashMap<>(Optional.ofNullable(additionalConfig).orElseGet(ImmutableMap::of));
            newConfig.put(SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, "");
            return oldConfig.toBuilder().additionalProperties(newConfig).build();
        }
        else if (platformConfig instanceof PlatformConsumerConfig) {
            PlatformConsumerConfig oldConfig = (PlatformConsumerConfig) platformConfig;
            Map<String, String> additionalConfig = platformConfig.additionalProperties();
            Map<String, String> newConfig = new HashMap<>(Optional.ofNullable(additionalConfig).orElseGet(ImmutableMap::of));
            newConfig.put(SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, "");
            return oldConfig.toBuilder().additionalProperties(newConfig).build();
        }
        return platformConfig;
    }

I am casting to producer or consumer config because the PlatformConfigurable interface doesn't have .toBuilder() or .build() methods declared in it, and I don't have access to modify the interface, as I can only implement it.

I would want to get rid of the duplicate code:

Map<String, String> additionalConfig = platformConfig.additionalProperties();
            Map<String, String> newConfig = new HashMap<>(Optional.ofNullable(additionalConfig).orElseGet(ImmutableMap::of));
            newConfig.put(SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, "");
            return oldConfig.toBuilder().additionalProperties(newConfig).build();

I was thinking of using lambdas, but I am not 100% sure how to do it.

Body:
Adding one thing in Alex Rudenko's answer, and making different function to add different implementations of interfaces.

private PlatformConfigurable disableHostNameVerificationConfig(PlatformConfigurable platformConfig) {
    if ((platformConfig == null)) {
        return platformConfig;
    }

    Map<String, String> additionalConfig = platformConfig.additionalProperties();
    Map<String, String> newConfig = new HashMap<>(Optional.ofNullable(additionalConfig).orElseGet(ImmutableMap::of));
    newConfig.put(SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, "");
    return PlatformConfigurableObject(platformConfig, newConfig);
}

So you can handle all instances in a different method, and whenever PlatfromXCofing classes are added later you only have to change this method. Single Responsibility Principle.

private PlatformConfigurable PlatformConfigurableObject(PlatformConfigurable platformConfig, Map<String, String> newConfig){
    if (platformConfig instanceof PlatformProducerConfig) {
        return ((PlatformProducerConfig)platformConfig).toBuilder().additionalProperties(newConfig).build();
    } else if (platformConfig instanceof PlatformConsumerConfig){
        return ((PlatformConsumerConfig)platformConfig).toBuilder().additionalProperties(newConfig).build();
    } else{
    return platformConfig;
    }
}


问:
NodeJS - https - TypeError [ERR_INVALID_HTTP_TOKEN]: Header name must be a valid HTTP token ["Accept"]
I have a NodeJS code that uses https module as: https.request(options, (res) => {...... where options is an object like

```<code>const options = {
    hostname: SERVICE_HOSTNAME,
    path: BASE_PATH,
    method: 'GET',
    headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        ApplicationId,
        Authorization
    }
  };
</code>```

My problems start when I add Accept header. I getting an error:

```<code>TypeError [ERR_INVALID_HTTP_TOKEN]: Header name must be a valid HTTP token ["Accept"]
    at ClientRequest.setHeader (_http_outgoing.js:472:3)
    at new ClientRequest (_http_client.js:203:14)
    at Object.request (https.js:289:10)
</code>```

How Accept header would be invalid?

答:
hlfrmn already found this tricky error and gave the correct answer, just in case anyone else is interested:

Starting from version 14.3.0 Node's http module will perform validateHeaderName and validateHeaderValue on each Key-Value pair you specify in your request options headers.

So if you do

```<code>const {validateHeaderName} = require('http');

try {
    const options = {
        method: 'GET',
        headers: {
            'Content-Type': 'application/json',
            'Accept': 'application/json',
        }
    };
    for (const header in options.headers) {
        validateHeaderName(header);
    }

} catch (err) {
    console.log(err);
}
</code>```

the mentioned error will be printed:

```<code>TypeError [ERR_INVALID_HTTP_TOKEN]: Header name must be a valid HTTP token ["Accept"] will be printed from the catch block.
</code>```

Body:
I have a NodeJS code that uses https module as: https.request(options, (res) => {...... where options is an object like

const options = {
    hostname: SERVICE_HOSTNAME,
    path: BASE_PATH,
    method: 'GET',
    headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        ApplicationId,
        Authorization
    }
  };

My problems start when I add Accept header. I getting an error:

TypeError [ERR_INVALID_HTTP_TOKEN]: Header name must be a valid HTTP token ["Accept"]
    at ClientRequest.setHeader (_http_outgoing.js:472:3)
    at new ClientRequest (_http_client.js:203:14)
    at Object.request (https.js:289:10)

How Accept header would be invalid?

Body:
hlfrmn already found this tricky error and gave the correct answer, just in case anyone else is interested:

Starting from version 14.3.0 Node's http module will perform validateHeaderName and validateHeaderValue on each Key-Value pair you specify in your request options headers.

So if you do

const {validateHeaderName} = require('http');

try {
    const options = {
        method: 'GET',
        headers: {
            'Content-Type': 'application/json',
            'Accept': 'application/json',
        }
    };
    for (const header in options.headers) {
        validateHeaderName(header);
    }

} catch (err) {
    console.log(err);
}

the mentioned error will be printed:

TypeError [ERR_INVALID_HTTP_TOKEN]: Header name must be a valid HTTP token ["Accept"] will be printed from the catch block.


问:
Weaviate Search Graph Vs. GA of IBM Graph
IBM Graph service is only compared to how it can add and store properties in the form of key/value pairs associated with the data, for both vertices and nodes connected by edges, rather than the more traditional form of storing the data in tabular form using rows and columns. However, how is the GA of IBM Graph compared to Knowledge Graph with Weaviate Search Graph (GraphQL - RESTful - Semantic Search - Semantic Classification - Knowledge Representation)?</p>

答:
The answer is based on the assumption that you mean JanusGraph because of this article.

JanusGraph is a Graph DBMS optimized for distributed clusters.

Weaviate is a GraphQL based semantic search engine.

The main difference is that JanusGraph focusses on large graphs whereas Weaviate focusses on search where results are represented in graph format.

You might pick JanusGraph if you want to store and analyze a large graph.

You might pick Weaviate if you build a search engine and/or store data in graph format.

Something Weaviate can do what other search engines (regardless if they are graph-based or not) is index your data semantically, e.g., you can find a data object about the publication Vogue by searching for fashion.

Weaviate query example:

Disclaimer:

I'm part of the team working on Weaviate.


问:
Sorting a list of RGB triplets into a spectrum
I have a list of RGB triplets, and I'd like to plot them in such a way that they form something like a spectrum.

I've converted them to HSV, which people seem to recommend.

```<code>from PIL import Image, ImageDraw
import colorsys

def make_rainbow_rgb(colors, width, height):
    """colors is an array of RGB tuples, with values between 0 and 255"""

    img = Image.new("RGBA", (width, height))
    canvas = ImageDraw.Draw(img)

    def hsl(x):
        to_float = lambda x : x / 255.0
        (r, g, b) = map(to_float, x)
        h, s, l = colorsys.rgb_to_hsv(r,g,b)
        h = h if 0 < h else 1 # 0 -> 1
        return h, s, l

    rainbow = sorted(colors, key=hsl)

    dx = width / float(len(colors))
    x = 0
    y = height / 2.0
    for rgb in rainbow:
        canvas.line((x, y, x + dx, y), width=height, fill=rgb)
        x += dx
    img.show()
</code>```

However, the result doesn't look very much like a nice rainbow-y spectrum. I suspect I need to either convert to a different color space or handle the HSL triplet differently.

Does anyone know what I need to do to make this data look roughly like a rainbow?

Update:

I was playing around with Hilbert curves and revisited this problem. Sorting the RGB values (same colors in both images) by their position along a Hilbert curve yields an interesting (if still not entirely satisfying) result:

答:
You're trying to convert a three-dimensional space into a one-dimensional space. There's no guarantee that you can make a pleasing rainbow out of it, as Oli says.

What you can do is "bucket" the colors into a few different categories based on saturation and value/lightness, and then sort within the categories, to get several independent gradients. For example, high-saturation colors first for the classic rainbow, then mid-saturation high-value colors (pastels), then low-saturation (grays).

Alternately, if all you care about is the rainbow, convert to hsl, then slam saturation to 1.0 and value to 0.5, convert back to rgb and render that instead of the original color.

Body:
I have a list of RGB triplets, and I'd like to plot them in such a way that they form something like a spectrum.

I've converted them to HSV, which people seem to recommend.

from PIL import Image, ImageDraw
import colorsys

def make_rainbow_rgb(colors, width, height):
    """colors is an array of RGB tuples, with values between 0 and 255"""

    img = Image.new("RGBA", (width, height))
    canvas = ImageDraw.Draw(img)

    def hsl(x):
        to_float = lambda x : x / 255.0
        (r, g, b) = map(to_float, x)
        h, s, l = colorsys.rgb_to_hsv(r,g,b)
        h = h if 0 < h else 1 # 0 -> 1
        return h, s, l

    rainbow = sorted(colors, key=hsl)

    dx = width / float(len(colors))
    x = 0
    y = height / 2.0
    for rgb in rainbow:
        canvas.line((x, y, x + dx, y), width=height, fill=rgb)
        x += dx
    img.show()

However, the result doesn't look very much like a nice rainbow-y spectrum. I suspect I need to either convert to a different color space or handle the HSL triplet differently.

Does anyone know what I need to do to make this data look roughly like a rainbow?

Update:

I was playing around with Hilbert curves and revisited this problem. Sorting the RGB values (same colors in both images) by their position along a Hilbert curve yields an interesting (if still not entirely satisfying) result:


问:
How to find if an SQL job is configured on which database of that SQL Server?
We have a situation where we need to get a report of which jobs are created to run queries on which databases in one of our SQL Server?

Appreciating your response.

答: have a look at this table: msdb.dbo.sysjobsteps</p>


问:
selenium web driver running as different user not getting profile/session of user
I have a strange situation where I have modified the selenium web driver code slightly to allow the driver service to be launched under a different user, changes to the code from github are:

```<code>public void Start()
    {
        this.driverServiceProcess = new Process();
        if (this.user != null)
        {
            this.driverServiceProcess.StartInfo.UserName = user.Name;
            this.driverServiceProcess.StartInfo.Password = user.Password;
            this.driverServiceProcess.StartInfo.Domain = user.Domain;
        }
        this.driverServiceProcess.StartInfo.FileName = Path.Combine(this.driverServicePath, this.driverServiceExecutableName);
        this.driverServiceProcess.StartInfo.Arguments = this.CommandLineArguments;
        this.driverServiceProcess.StartInfo.UseShellExecute = false;
        this.driverServiceProcess.StartInfo.CreateNoWindow = this.hideCommandPromptWindow;
        this.driverServiceProcess.Start();
        bool serviceAvailable = this.WaitForServiceInitialization();

        if (!serviceAvailable)
        {
            string msg = "Cannot start the driver service on " + this.ServiceUrl;
            throw new WebDriverException(msg);
        }
    }
</code>```

where the user details are passed in from my external code in the call to instantiate the web driver:

```<code>new ChromeDriver(userName, password, domain);
</code>```

or

```<code>new InternetExplorerDriver(ieOptions, userName, password, domain);
</code>```

and propagated through.

This successfully launches the chrome driver under the required user credentials, but has a problem with IE.

Additionally the chrome driver does not have the same behavior as chrome launched as the given user manually (i.e. not through a selenium driver).  Specifically the automatic passing of user credentials on an NTLM challenge does not occur.

I have discovered that if I have an interactive session running as the desired user (simply use runas /user:<theUser> cmd.exe from the command line and leave the session open) then all of the functionality of the the browsers is as expected when launched through the selenium web driver, including automatically responding to the NTLM challenge.

If I use Process.Start() to launch cmd.exe as the desired user before creating the web driver this does not work.

My question is this:

What is different about launching a process programatically (using Process.Start()) compared to launching an interactive session of the process from the command line?

And is there any way I can faithfully reproduce the effect of launching a session from the command line in code so that I can automate the process and get my web drivers to perform as I desire?

note: I tried launching the webdriver using .net impersonation (as suggested here and here) rather than modifying the selenium code to run the driver service under another user, but the requests sent from the driver to a server were all sent under my user rather than the one specified by the impersonation (see here)

答:
This technique is no longer required in current Selenium .NET sources. The DriverProcessStarting event now allows the user to modify the ProcessStartInfo object used to start the driver service process. The code to accomplish this would look something like the following:

Assuming your user object looks something like this:

```<code>public class User
{
    public string UserName { get; set; }
    public SecureString Password { get; set; }
    public string Domain { get; set; }
    public bool LoadUserProfile { get; set; }
}
</code>```

You could use something like the following:

```<code>public IWebDriver StartInternetExplorerDriver(InternetExplorerOptions options, User user)
{
    InternetExplorerDriverService service = InternetExplorerDriverService.CreateDefaultService();
    service.DriverProcessStarting += (object sender, DriverProcessStartingEventArgs e) =>
    {
        e.DriverServiceProcessStartInfo.UserName = user.UserName;
        e.DriverServiceProcessStartInfo.Password = user.Password;
        e.DriverServiceProcessStartInfo.Domain = user.Domain;
        e.DriverServiceProcessStartInfo.LoadUserProfile = user.LoadUserProfile;
    };

    return new InternetExplorerDriver(service, options);
}
</code>```

Body:
I have a strange situation where I have modified the selenium web driver code slightly to allow the driver service to be launched under a different user, changes to the code from github are:

public void Start()
    {
        this.driverServiceProcess = new Process();
        if (this.user != null)
        {
            this.driverServiceProcess.StartInfo.UserName = user.Name;
            this.driverServiceProcess.StartInfo.Password = user.Password;
            this.driverServiceProcess.StartInfo.Domain = user.Domain;
        }
        this.driverServiceProcess.StartInfo.FileName = Path.Combine(this.driverServicePath, this.driverServiceExecutableName);
        this.driverServiceProcess.StartInfo.Arguments = this.CommandLineArguments;
        this.driverServiceProcess.StartInfo.UseShellExecute = false;
        this.driverServiceProcess.StartInfo.CreateNoWindow = this.hideCommandPromptWindow;
        this.driverServiceProcess.Start();
        bool serviceAvailable = this.WaitForServiceInitialization();

        if (!serviceAvailable)
        {
            string msg = "Cannot start the driver service on " + this.ServiceUrl;
            throw new WebDriverException(msg);
        }
    }

where the user details are passed in from my external code in the call to instantiate the web driver:

new ChromeDriver(userName, password, domain);

or

new InternetExplorerDriver(ieOptions, userName, password, domain);

and propagated through.

This successfully launches the chrome driver under the required user credentials, but has a problem with IE.

Additionally the chrome driver does not have the same behavior as chrome launched as the given user manually (i.e. not through a selenium driver).  Specifically the automatic passing of user credentials on an NTLM challenge does not occur.

I have discovered that if I have an interactive session running as the desired user (simply use runas /user:<theUser> cmd.exe from the command line and leave the session open) then all of the functionality of the the browsers is as expected when launched through the selenium web driver, including automatically responding to the NTLM challenge.

If I use Process.Start() to launch cmd.exe as the desired user before creating the web driver this does not work.

My question is this:

What is different about launching a process programatically (using Process.Start()) compared to launching an interactive session of the process from the command line?

And is there any way I can faithfully reproduce the effect of launching a session from the command line in code so that I can automate the process and get my web drivers to perform as I desire?

note: I tried launching the webdriver using .net impersonation (as suggested here and here) rather than modifying the selenium code to run the driver service under another user, but the requests sent from the driver to a server were all sent under my user rather than the one specified by the impersonation (see here)

Body:
This technique is no longer required in current Selenium .NET sources. The DriverProcessStarting event now allows the user to modify the ProcessStartInfo object used to start the driver service process. The code to accomplish this would look something like the following:

Assuming your user object looks something like this:

public class User
{
    public string UserName { get; set; }
    public SecureString Password { get; set; }
    public string Domain { get; set; }
    public bool LoadUserProfile { get; set; }
}

You could use something like the following:

public IWebDriver StartInternetExplorerDriver(InternetExplorerOptions options, User user)
{
    InternetExplorerDriverService service = InternetExplorerDriverService.CreateDefaultService();
    service.DriverProcessStarting += (object sender, DriverProcessStartingEventArgs e) =>
    {
        e.DriverServiceProcessStartInfo.UserName = user.UserName;
        e.DriverServiceProcessStartInfo.Password = user.Password;
        e.DriverServiceProcessStartInfo.Domain = user.Domain;
        e.DriverServiceProcessStartInfo.LoadUserProfile = user.LoadUserProfile;
    };

    return new InternetExplorerDriver(service, options);
}


问:
MVC2 in jsp/servlet application
Here's the scenario, I am working on a web-based application develped used JSP/Servlet technique, and we adopt MVC2 as an architectural design pattern, we put all the methods that make manipulation on database into one class, for example, addNewUser() , updateUserInfo (),
all methods that make connection to db and manipulate data are in one class.

what is the role of this class, controller or model?

答:
That's the (business) model.

The controller should be the servlet and the view should be the JSP.

Title: MVC2 in jsp/servlet application


问:
Docusign add note in a template and prefill it before sending the envelope
i need to enter the signer address in a template docusign as a note field and prefill it when creating the envelope and before sending it. Thanks for help.

there is my php code:

```<code>$envelope_definition = new EnvelopeDefinition([
    'status' => 'sent', 'template_id' => $this->template_id
]);
# Create the template role elements to connect the signer and cc recipients
# to the template

$signer = new TemplateRole([
    'email'             => $args['signer_email'],
    'name'              => $args['signer_name'],
    'role_name'         => 'signer'
]);
</code>```

$address_note = new Note(['selected' => 'true', 'tab_label' => 'signer_address', 'value' => $args['signer_address']]);
$signer->setTabs(new Tabs([$address_note]));
$envelope_definition->setTemplateRoles([$signer]);

and there is the configuration of note field in the dashboard docusign: note field

But the problem is when signing the document i can't see the signer address

When i try to find the tabs in the apropriate template using this php code :

```<code># create the envelope definition with the template_id
    $envelope_definition = new EnvelopeDefinition([
        'status' => 'sent', 'template_id' => $this->template_id
    ]);
    # Create the template role elements to connect the signer and cc recipients
    # to the template

    $signer = new TemplateRole([
        'email'             => $args['signer_email'],
        'name'              => $args['signer_name'],
        'role_name'         => 'signer'
    ]);

    dd($signer->getTabs());
</code>```

i got null as result.

答:
Thanks for your help, i resolve the issue, the solution is : </p>

```<code>    $envelope_definition = new EnvelopeDefinition([
        'status' => 'sent', 'template_id' => $this->template_id
    ]);

    $address_note = new Note(['selected' => "true", 'tab_label' => 'signer_address', 'value' => $args['signer_address']]);
    $tabs = new Tabs(['note_tabs' => [$address_note]]);
    $signer = new TemplateRole([
        'email'             => $args['signer_email'],
        'name'              => $args['signer_name'],
        'role_name'         => 'signer',
        'tabs'              => $tabs
    ]);
</code>```

Body:
i need to enter the signer address in a template docusign as a note field and prefill it when creating the envelope and before sending it. Thanks for help.

there is my php code:

$envelope_definition = new EnvelopeDefinition([
    'status' => 'sent', 'template_id' => $this->template_id
]);
# Create the template role elements to connect the signer and cc recipients
# to the template

$signer = new TemplateRole([
    'email'             => $args['signer_email'],
    'name'              => $args['signer_name'],
    'role_name'         => 'signer'
]);

$address_note = new Note(['selected' => 'true', 'tab_label' => 'signer_address', 'value' => $args['signer_address']]);
$signer->setTabs(new Tabs([$address_note]));
$envelope_definition->setTemplateRoles([$signer]);

and there is the configuration of note field in the dashboard docusign: note field

But the problem is when signing the document i can't see the signer address

When i try to find the tabs in the apropriate template using this php code :

# create the envelope definition with the template_id
    $envelope_definition = new EnvelopeDefinition([
        'status' => 'sent', 'template_id' => $this->template_id
    ]);
    # Create the template role elements to connect the signer and cc recipients
    # to the template

    $signer = new TemplateRole([
        'email'             => $args['signer_email'],
        'name'              => $args['signer_name'],
        'role_name'         => 'signer'
    ]);

    dd($signer->getTabs());

i got null as result.

Body:
Thanks for your help, i resolve the issue, the solution is :

    $envelope_definition = new EnvelopeDefinition([
        'status' => 'sent', 'template_id' => $this->template_id
    ]);

    $address_note = new Note(['selected' => "true", 'tab_label' => 'signer_address', 'value' => $args['signer_address']]);
    $tabs = new Tabs(['note_tabs' => [$address_note]]);
    $signer = new TemplateRole([
        'email'             => $args['signer_email'],
        'name'              => $args['signer_name'],
        'role_name'         => 'signer',
        'tabs'              => $tabs
    ]);


问:
LDAP reset password from outside the domain network C# Error: RPC server is unavailable. (exception from hresult: 0x800706ba)
We're trying to Reset LDAP password, its working on development environment but not working on production environment.

Our development environment is inside the Domain and production environment is outside the Domain.

In development to connect LDAP, we have used Domain name like abc.com and production environment we use IPaddress:389, which is already working for LDAP User authentication in both environment. But not working for LDAP reset password.

```<code>Error: RPC server is unavailable. (exception from hresult: 0x800706ba)
</code>```

Developement: (working)

```<code>PrincipalContext principalContext =
    new PrincipalContext(ContextType.Domain, "<domain.com>", container: "<DC=domain,DC=com>",
    "<username>", "<password>");
UserPrincipal user = UserPrincipal.FindByIdentity(principalContext, "<LdapUserName>");
// "<username>", "<password>" are Administrative credential.
bool isValid = user.ValidateCredentials("<username>", "<password>");
_logger.Log($"Is Connection: {isValid}");
**// Output: Is Connection: True**
user.UserCannotChangePassword = false;
user.SetPassword("<NewPassword>");
// Password has been successfully reset.
</code>```

Production: (working)
Also we are authenticate LDAP users using below method its working on Production:

Check user has LDAP account or not:

```<code>// "<username>", "<password>" are Administrative credential.
var entry = new DirectoryEntry($"LDAP://{"<IP:389>"}", "<username>", "<password>",
    AuthenticationTypes.Secure | AuthenticationTypes.Sealing | AuthenticationTypes.ServerBind);
var search = new DirectorySearcher(entry);
var strFilter = $"(mail={"<UserEmailId>"})";
search.Filter = strFilter;
var result = await Task.Run(() => search.FindOne());
if (result != null)
{
    //IsLdapUser = true;
    //result.Properties["samaccountname"][0]);
}
else
{
    //IsLdapUser = false;
}
// Successfully

// Authenticate LDAP user:
var ldapConnection = new LdapConnection(new LdapDirectoryIdentifier("<IP:389>", false, false));
var nc = new NetworkCredential("<LdapUserName>", "<LdapUserPassword>", "<IP:389>");
ldapConnection.Credential = nc;
ldapConnection.AuthType = AuthType.Negotiate;
ldapConnection.Bind(nc);
// Successfully

</code>```

Production: (not working)

```<code>// "<username>", "<password>" are Administrative credential.
PrincipalContext principalContext =
    new PrincipalContext(ContextType.Domain, "<IP:389>", container: "<DC=domain,DC=com>",
    "<username>", "<password>");
UserPrincipal user = UserPrincipal.FindByIdentity(principalContext, "<LdapUserName>");
bool isValid = user.ValidateCredentials("<username>", "<password>");
_logger.Log($"Is Connection: {isValid}");
**// Output: Is Connection: True**
user.UserCannotChangePassword = false;
user.SetPassword("<NewPassword>");
// Error: RPC server is unavailable. (exception from hresult: 0x800706ba)
</code>```

Also tried with below code (not working)

```<code>// "<username>", "<password>" are Administrative credential.
DirectoryEntry de = new DirectoryEntry("<IP:389>","<username>", "<password>",
AuthenticationTypes.Secure | AuthenticationTypes.Sealing | AuthenticationTypes.ServerBind);
// LDAP Search Filter
DirectorySearcher ds = new DirectorySearcher(de);
ds.Filter = "(&(objectClass=user)(|(sAMAccountName=" + "<LdapUserName>"+ ")))";

// LDAP Properties to Load
ds.PropertiesToLoad.Add("displayName");
ds.PropertiesToLoad.Add("sAMAccountName");
ds.PropertiesToLoad.Add("DistinguishedName");
ds.PropertiesToLoad.Add("CN");

// Execute Search
SearchResult result = await Task.Run(() => ds.FindOne());

string dn = result.Properties["DistinguishedName"][0].ToString();

DirectoryEntry uEntry = result.GetDirectoryEntry();

uEntry.Invoke("SetPassword", new object[] { "<NewPassword>"});  //Set New Password
uEntry.CommitChanges();
uEntry.Close();
// Error: RPC server is unavailable. (exception from hresult: 0x800706ba)
</code>```

答:
The attribute used to modify the password is unicodePwd. That documentation reveals some conditions that must be met for the password to be changed. Primarily, the connection must be encrypted.

Calling .Invoke("SetPassword", ...) actually calls the native Windows IADsUser::SetPassword method. That documentation shows that it automatically attempts a few different ways to encrypt. The exception happens because none of these methods worked.

You can actually modify the unicodePwd attribute directly, without calling SetPassword, which I'll get to, but regardless, you have to resolve the issue of encryption first.

When you're running this from a computer inside the network, AuthenticationTypes.Sealing is enough. As the documentation says, the effect is that it uses Kerberos to encrypt the connection.

But when you're connecting from outside the domain, Kerberos won't work (maybe it will with effort - I'm no Kerberos expert). So the only usable encryption method is SSL. The SetPassword method does actually attempt to use SSL, but clearly it didn't work.

One problem I see right away is that you're using an IP address to connect to the DC, and SSL won't work using an IP address, since the domain name name on the SSL certificate must match the name you are using to access to the server, and the SSL cert will not have the IP address on it. So you will have to change that to use the domain name. If DNS will not resolve the name, you can add it to your hosts file.

Changing that may fix everything. If not, there can be two other issues:

Port 636 is not accessible (a firewall in the way).

The SSL certificate is not trusted on the computer you run this on

LDAP over SSL (LDAPS) works on port 636. You can test this connection in PowerShell:

```<code>Test-NetConnection example.com -Port 636
</code>```

If that fails, fix that first.

Next, check the certificate. You can download the certificate with this PowerShell script:

```<code>$webRequest = [Net.WebRequest]::Create("https://example.com:636")
try { $webRequest.GetResponse() } catch {}
$cert = $webRequest.ServicePoint.Certificate
$bytes = $cert.Export([Security.Cryptography.X509Certificates.X509ContentType]::Cert)
set-content -value $bytes -encoding byte -path "certificate.cer"
</code>```

Change the example.com in the first line to your domain name (leave the https:// and :636). Then you will have a file called certificate.cer in the current directory that you can open and inspect. It will warn you if it is not trusted. If it's not trusted, then you will have to install the root certificate on the server as a Trusted Root Certificate.

If it is already trusted, make sure the "Issued to:" domain name on the cert matches the name you used to connect. In our environment, the SSL certificates are in the name of each domain controller (dc1.example.com), not the domain name (example.com). So I have to target a specific domain controller for LDAPS to work.

Once you get all of that sorted out, your code should work.

If you want to change the unicodePwd attribute directly instead of using SetPassword (which may or may not perform a little faster), you will need to make the original connection via SSL. For example:

```<code>DirectoryEntry de = new DirectoryEntry("LDAP://dc1.example.com:636","<username>", "<password>",
    AuthenticationTypes.Secure | AuthenticationTypes.SecureSocketsLayer | AuthenticationTypes.ServerBind);
</code>```

Only use AuthenticationTypes.ServerBind if you are targeting a specific DC.

Then you can update the unicodePwd attribute in the very specific way that it wants:

```<code>uEntry.Properties["unicodePwd"].Value = Encoding.Unicode.GetBytes("\"NewPassword\"");
uEntry.CommitChanges();
</code>```

Note that the new password must be enclosed in quotes.

Body:
We're trying to Reset LDAP password, its working on development environment but not working on production environment.

Our development environment is inside the Domain and production environment is outside the Domain.

In development to connect LDAP, we have used Domain name like abc.com and production environment we use IPaddress:389, which is already working for LDAP User authentication in both environment. But not working for LDAP reset password.

Error: RPC server is unavailable. (exception from hresult: 0x800706ba)

Developement: (working)

PrincipalContext principalContext =
    new PrincipalContext(ContextType.Domain, "<domain.com>", container: "<DC=domain,DC=com>",
    "<username>", "<password>");
UserPrincipal user = UserPrincipal.FindByIdentity(principalContext, "<LdapUserName>");
// "<username>", "<password>" are Administrative credential.
bool isValid = user.ValidateCredentials("<username>", "<password>");
_logger.Log($"Is Connection: {isValid}");
**// Output: Is Connection: True**
user.UserCannotChangePassword = false;
user.SetPassword("<NewPassword>");
// Password has been successfully reset.

Production: (working)
Also we are authenticate LDAP users using below method its working on Production:

Check user has LDAP account or not:

// "<username>", "<password>" are Administrative credential.
var entry = new DirectoryEntry($"LDAP://{"<IP:389>"}", "<username>", "<password>",
    AuthenticationTypes.Secure | AuthenticationTypes.Sealing | AuthenticationTypes.ServerBind);
var search = new DirectorySearcher(entry);
var strFilter = $"(mail={"<UserEmailId>"})";
search.Filter = strFilter;
var result = await Task.Run(() => search.FindOne());
if (result != null)
{
    //IsLdapUser = true;
    //result.Properties["samaccountname"][0]);
}
else
{
    //IsLdapUser = false;
}
// Successfully

// Authenticate LDAP user:
var ldapConnection = new LdapConnection(new LdapDirectoryIdentifier("<IP:389>", false, false));
var nc = new NetworkCredential("<LdapUserName>", "<LdapUserPassword>", "<IP:389>");
ldapConnection.Credential = nc;
ldapConnection.AuthType = AuthType.Negotiate;
ldapConnection.Bind(nc);
// Successfully

Production: (not working)

// "<username>", "<password>" are Administrative credential.
PrincipalContext principalContext =
    new PrincipalContext(ContextType.Domain, "<IP:389>", container: "<DC=domain,DC=com>",
    "<username>", "<password>");
UserPrincipal user = UserPrincipal.FindByIdentity(principalContext, "<LdapUserName>");
bool isValid = user.ValidateCredentials("<username>", "<password>");
_logger.Log($"Is Connection: {isValid}");
**// Output: Is Connection: True**
user.UserCannotChangePassword = false;
user.SetPassword("<NewPassword>");
// Error: RPC server is unavailable. (exception from hresult: 0x800706ba)

Also tried with below code (not working)

// "<username>", "<password>" are Administrative credential.
DirectoryEntry de = new DirectoryEntry("<IP:389>","<username>", "<password>",
AuthenticationTypes.Secure | AuthenticationTypes.Sealing | AuthenticationTypes.ServerBind);
// LDAP Search Filter
DirectorySearcher ds = new DirectorySearcher(de);
ds.Filter = "(&(objectClass=user)(|(sAMAccountName=" + "<LdapUserName>"+ ")))";

// LDAP Properties to Load
ds.PropertiesToLoad.Add("displayName");
ds.PropertiesToLoad.Add("sAMAccountName");
ds.PropertiesToLoad.Add("DistinguishedName");
ds.PropertiesToLoad.Add("CN");

// Execute Search
SearchResult result = await Task.Run(() => ds.FindOne());

string dn = result.Properties["DistinguishedName"][0].ToString();

DirectoryEntry uEntry = result.GetDirectoryEntry();

uEntry.Invoke("SetPassword", new object[] { "<NewPassword>"});  //Set New Password
uEntry.CommitChanges();
uEntry.Close();
// Error: RPC server is unavailable. (exception from hresult: 0x800706ba)

Body:
The attribute used to modify the password is unicodePwd. That documentation reveals some conditions that must be met for the password to be changed. Primarily, the connection must be encrypted.

Calling .Invoke("SetPassword", ...) actually calls the native Windows IADsUser::SetPassword method. That documentation shows that it automatically attempts a few different ways to encrypt. The exception happens because none of these methods worked.

You can actually modify the unicodePwd attribute directly, without calling SetPassword, which I'll get to, but regardless, you have to resolve the issue of encryption first.

When you're running this from a computer inside the network, AuthenticationTypes.Sealing is enough. As the documentation says, the effect is that it uses Kerberos to encrypt the connection.

But when you're connecting from outside the domain, Kerberos won't work (maybe it will with effort - I'm no Kerberos expert). So the only usable encryption method is SSL. The SetPassword method does actually attempt to use SSL, but clearly it didn't work.

One problem I see right away is that you're using an IP address to connect to the DC, and SSL won't work using an IP address, since the domain name name on the SSL certificate must match the name you are using to access to the server, and the SSL cert will not have the IP address on it. So you will have to change that to use the domain name. If DNS will not resolve the name, you can add it to your hosts file.

Changing that may fix everything. If not, there can be two other issues:

Port 636 is not accessible (a firewall in the way).

The SSL certificate is not trusted on the computer you run this on

LDAP over SSL (LDAPS) works on port 636. You can test this connection in PowerShell:

Test-NetConnection example.com -Port 636

If that fails, fix that first.

Next, check the certificate. You can download the certificate with this PowerShell script:

$webRequest = [Net.WebRequest]::Create("https://example.com:636")
try { $webRequest.GetResponse() } catch {}
$cert = $webRequest.ServicePoint.Certificate
$bytes = $cert.Export([Security.Cryptography.X509Certificates.X509ContentType]::Cert)
set-content -value $bytes -encoding byte -path "certificate.cer"

Change the example.com in the first line to your domain name (leave the https:// and :636). Then you will have a file called certificate.cer in the current directory that you can open and inspect. It will warn you if it is not trusted. If it's not trusted, then you will have to install the root certificate on the server as a Trusted Root Certificate.

If it is already trusted, make sure the "Issued to:" domain name on the cert matches the name you used to connect. In our environment, the SSL certificates are in the name of each domain controller (dc1.example.com), not the domain name (example.com). So I have to target a specific domain controller for LDAPS to work.

Once you get all of that sorted out, your code should work.

If you want to change the unicodePwd attribute directly instead of using SetPassword (which may or may not perform a little faster), you will need to make the original connection via SSL. For example:

DirectoryEntry de = new DirectoryEntry("LDAP://dc1.example.com:636","<username>", "<password>",
    AuthenticationTypes.Secure | AuthenticationTypes.SecureSocketsLayer | AuthenticationTypes.ServerBind);

Only use AuthenticationTypes.ServerBind if you are targeting a specific DC.

Then you can update the unicodePwd attribute in the very specific way that it wants:

uEntry.Properties["unicodePwd"].Value = Encoding.Unicode.GetBytes("\"NewPassword\"");
uEntry.CommitChanges();

Note that the new password must be enclosed in quotes.


问:
Can Azure Data Catalog be used to connect to on-premise databases and ingest metadata? If yes, is data profiling available?
Most of the data that we would need to learn about and document in Azure Data Catalog currently resides on Premise in SQL Server databases.

Can Azure Data Catalog connect to these data sources, and serve-up metadata for data assets that are NOT stored in Azure?

答: The majority of our data sources are on-premises so the answer is, yes! Please see https://learn.microsoft.com/en-us/azure/data-catalog/data-catalog-dsr for details.</p>


问:
Get element from JsonNode array
I have this json:

```<code>{
    "text":[
        {"a":1},
        {"b":2}
    ]
}
</code>```

I have this code:

```<code>JsonNode jsonNode = (new ObjectMapper()).readTree(jsonString);

//get first element from "text"
//this is just an explanation of what i want

String aValue = jsonNode.get("text")[0]
                        .get("a")
                        .asText();
</code>```

How I can done that, without mapping it to an object?

Or do something like JsonNode[] array and array[0] represent a and array[1] represent b

答:
If you want to explicitly traverse through the json and find the value of a , you can do it like this for the json that you specified.

```<code>String aValue = jsonNode.get("text").get(0).get("a").asText();
</code>```

Finding the value of b would be

```<code>String bValue = jsonNode.get("text").get(1).get("b").asText();
</code>```

You can also traverse through the elements within the text array and get the values of a and b as

```<code>for (JsonNode node : jsonNode.get("text")) {
    System.out.println(node.fields().next().getValue().asText());
}
</code>```

And that would print the below on the console

```<code>1
2
</code>```

Title: Get element from JsonNode array

Body:
I have this json:

{
    "text":[
        {"a":1},
        {"b":2}
    ]
}

I have this code:

JsonNode jsonNode = (new ObjectMapper()).readTree(jsonString);

//get first element from "text"
//this is just an explanation of what i want

String aValue = jsonNode.get("text")[0]
                        .get("a")
                        .asText();

How I can done that, without mapping it to an object?

Or do something like JsonNode[] array and array[0] represent a and array[1] represent b

Body:
If you want to explicitly traverse through the json and find the value of a , you can do it like this for the json that you specified.

String aValue = jsonNode.get("text").get(0).get("a").asText();

Finding the value of b would be

String bValue = jsonNode.get("text").get(1).get("b").asText();

You can also traverse through the elements within the text array and get the values of a and b as

for (JsonNode node : jsonNode.get("text")) {
    System.out.println(node.fields().next().getValue().asText());
}

And that would print the below on the console

1
2


问:
Merging several lists to create a data frame in R
Apologies in advance if this has already been asked elsewhere, but I've tried different attempts and nothing has worked so far.

I study the data from 23 devices mesuring air pollution. For each device, I am interested in 4 parameters (mean, max, min and std). I finally obtain 4 lists with 23 values, representing the parameters for each device.

```<code>    var_names <- ls(envir = globalenv(), pattern = "^Device")
    Corrected_values<- mget(var_names)

    Device_mean <- lapply(Corrected_values, mean)
    Device_max <- lapply(Corrected_values, max)
    Device_min <- lapply(Corrected_values, min)
    Device_sd <- lapply(Corrected_values, sd)
</code>```

Now I wish to create a data frame "Device" that will be a merge of these 4 lists. This data frame (or matrix) with 4 columns and 23 rows will then be exportable for further uses. Up to now, all my attempts resulted in a wrong matrix.

```<code>    # rename the column names
    cols <- c("Mean", "Maximum", "Minimum", "Stdv")
</code>```

Thanks for you help

答:
Here is a base R way.

```<code>var_names <- ls(envir = globalenv(), pattern = "^Device")
Corrected_values <- mget(var_names)
f <- function(x){
  data.frame(Mean = mean(x), Maximum = max(x), Minimum = min(x), Stdv = sd(x))
}

do.call(rbind, Map(f, Corrected_values))
#         Mean Maximum Minimum      Stdv
#Device1 5.006     5.8     4.3 0.3524897
#Device2 6.588     7.9     4.9 0.6358796
#Device3 5.936     7.0     4.9 0.5161711
</code>```

Data

```<code>Device1 <- iris[iris$Species == 'setosa', 'Sepal.Length']
Device2 <- iris[iris$Species == 'virginica', 'Sepal.Length']
Device3 <- iris[iris$Species == 'versicolor', 'Sepal.Length']
</code>```

Body:
Apologies in advance if this has already been asked elsewhere, but I've tried different attempts and nothing has worked so far.

I study the data from 23 devices mesuring air pollution. For each device, I am interested in 4 parameters (mean, max, min and std). I finally obtain 4 lists with 23 values, representing the parameters for each device.

    var_names <- ls(envir = globalenv(), pattern = "^Device")
    Corrected_values<- mget(var_names)

    Device_mean <- lapply(Corrected_values, mean)
    Device_max <- lapply(Corrected_values, max)
    Device_min <- lapply(Corrected_values, min)
    Device_sd <- lapply(Corrected_values, sd)

Now I wish to create a data frame "Device" that will be a merge of these 4 lists. This data frame (or matrix) with 4 columns and 23 rows will then be exportable for further uses. Up to now, all my attempts resulted in a wrong matrix.

    # rename the column names
    cols <- c("Mean", "Maximum", "Minimum", "Stdv")

Thanks for you help

Body:
Here is a base R way.

var_names <- ls(envir = globalenv(), pattern = "^Device")
Corrected_values <- mget(var_names)
f <- function(x){
  data.frame(Mean = mean(x), Maximum = max(x), Minimum = min(x), Stdv = sd(x))
}

do.call(rbind, Map(f, Corrected_values))
#         Mean Maximum Minimum      Stdv
#Device1 5.006     5.8     4.3 0.3524897
#Device2 6.588     7.9     4.9 0.6358796
#Device3 5.936     7.0     4.9 0.5161711

Data

Device1 <- iris[iris$Species == 'setosa', 'Sepal.Length']
Device2 <- iris[iris$Species == 'virginica', 'Sepal.Length']
Device3 <- iris[iris$Species == 'versicolor', 'Sepal.Length']