问:
Sort table when new data is entered in D, but follow this entry to new position
I've a basic code for sorting an excel table, and it works well:

```<code>Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Range("C3", Range("C3").End(xlDown)).Sort Key1:=Range("C3"), Order1:=xlAscending, Header:=xlYes
End Sub
</code>```

However, its a hassle to find the entry in a large table when data is entered in C. Would it be possible to follow the record to its new position when it is sorted? If yes, how can I correct the code to do so?

Thank you!

答:
There are number of way to do it. One of them is presented below.

Instead of Worksheet_SelectionChange(), the following solution use Worksheet_Change(). The idea is to store the newly added value (the followings assumes u to type in column C directly to add new value. If you have a specific location in column D, change the if condition to check for change at that location.) and then search for it after sorting. It will scroll to the newly added value after sorting every time a new value is added. You may adjust to fit your usage.

```<code>Private Sub Worksheet_Change(ByVal Target As Range)
    Dim val As Variant
    If Target.Column = 3 Then
        val = Target.Value

        Range("C3", Range("C3").End(xlDown)).Sort Key1:=Range("C3"), Order1:=xlAscending, Header:=xlYes

        ActiveWindow.ScrollRow = Application.WorksheetFunction.Match(val, Range("C3", Range("C3").End(xlDown)), 0) + 2
    End If
End Sub

</code>```

Body:
I've a basic code for sorting an excel table, and it works well:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Range("C3", Range("C3").End(xlDown)).Sort Key1:=Range("C3"), Order1:=xlAscending, Header:=xlYes
End Sub

However, its a hassle to find the entry in a large table when data is entered in C. Would it be possible to follow the record to its new position when it is sorted? If yes, how can I correct the code to do so?

Thank you!

Body:
There are number of way to do it. One of them is presented below.

Instead of Worksheet_SelectionChange(), the following solution use Worksheet_Change(). The idea is to store the newly added value (the followings assumes u to type in column C directly to add new value. If you have a specific location in column D, change the if condition to check for change at that location.) and then search for it after sorting. It will scroll to the newly added value after sorting every time a new value is added. You may adjust to fit your usage.

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim val As Variant
    If Target.Column = 3 Then
        val = Target.Value

        Range("C3", Range("C3").End(xlDown)).Sort Key1:=Range("C3"), Order1:=xlAscending, Header:=xlYes

        ActiveWindow.ScrollRow = Application.WorksheetFunction.Match(val, Range("C3", Range("C3").End(xlDown)), 0) + 2
    End If
End Sub


来源: stackexchange

问:
Hello, I am a bit stuck in react forms while updating the state
```<code>import React from "react";
import "./styles.css";

class App extends React.Component {
    constructor() {
        super();
        this.state = {
            user: {
                id: [1, 2, 3, 4],
                name: ["john", "wick", "james", null],
                city: ["paris", "berlin", "new york", "sydney"],
            },
            updatedValues: {
                id: null,
                name: null,
                city: null,
            },
        };
        this.updateToApi = this.updateToApi.bind(this);
        this.updateState = this.updateState.bind(this);
    }
    handleSubmit = (e) => {
        e.preventDefault();
    };
    handleUserChange = (e) => {
        const data = { ...this.state.updatedValues };
        data[e.currentTarget.name] = e.currentTarget.value;
        this.setState({
            data,
        });
    };
    updateToApi() {
        //updating the values to api using the this.state.updatedValues
    }
    updateState = () => {
        this.setState({
            updatedValues: {
                id: this.state.user.id,
                name: this.state.user.name,
                city: this.state.user.city,
            },
        });
    };
    render() {
        console.log(this.state);
        return (
            <div className="App">
                {this.state.user.id.map((id, index) => {
                    return (
                        <form onSubmit={this.handleSubmit}>
                            <input
                                type="text"
                                name="id"
                                placeholder="id "
                                defaultValue={id}
                                onChange={this.handleUserChange}
                            />
                            ,
                            <input
                                type="text"
                                name="name"
                                placeholder="name"
                                defaultValue={
                                    this.state.user.name[index]
                                        ? this.state.user.name[index]
                                        : this.state.updatedValues
                                }
                                onChange={
                                    this.state.user.name[index] !== "undefined"
                                        ? this.updateState
                                        : this.handleUserChange
                                }
                            />
                            ,
                            <input
                                type="text"
                                name="city"
                                placeholder="city"
                                defaultValue={this.state.user.city[index]}
                                onChange={this.handleUserChange}
                            />
                        </form>
                    );
                })}
            </div>
        );
    }
}
</code>```

this is a sample of what I am trying to achieve, I want the form to be filled with the values present in the user state and when I change the values in the text field it should update the whole updatetoApi function so that the db can receive the new values. The problem i faced is that when I change only one values then it will basically send a post request to api with only the one updated value of the respective field and all the other values will be overwrited with null

I have a sample that i tried
https://codesandbox.io/s/nice-hodgkin-t20v0

答:
You need a little null check in the function, calling the API:</p>

```<code>updateToApi() {
  if(this.state.updatedValues.id &&
   this.state.updatedValues.name &&
   this.state.updatedValues.city){
     //updating the values to api using the this.state.updatedValues
  }
}
</code>```

ContentLicense: CC BY-SA 4.0

Body:
import React from "react";
import "./styles.css";

class App extends React.Component {
    constructor() {
        super();
        this.state = {
            user: {
                id: [1, 2, 3, 4],
                name: ["john", "wick", "james", null],
                city: ["paris", "berlin", "new york", "sydney"],
            },
            updatedValues: {
                id: null,
                name: null,
                city: null,
            },
        };
        this.updateToApi = this.updateToApi.bind(this);
        this.updateState = this.updateState.bind(this);
    }
    handleSubmit = (e) => {
        e.preventDefault();
    };
    handleUserChange = (e) => {
        const data = { ...this.state.updatedValues };
        data[e.currentTarget.name] = e.currentTarget.value;
        this.setState({
            data,
        });
    };
    updateToApi() {
        //updating the values to api using the this.state.updatedValues
    }
    updateState = () => {
        this.setState({
            updatedValues: {
                id: this.state.user.id,
                name: this.state.user.name,
                city: this.state.user.city,
            },
        });
    };
    render() {
        console.log(this.state);
        return (

                {this.state.user.id.map((id, index) => {
                    return (
                        <form onSubmit={this.handleSubmit}>
                            <input
                                type="text"
                                name="id"
                                placeholder="id "
                                defaultValue={id}
                                onChange={this.handleUserChange}
                            />
                            ,
                            <input
                                type="text"
                                name="name"
                                placeholder="name"
                                defaultValue={
                                    this.state.user.name[index]
                                        ? this.state.user.name[index]
                                        : this.state.updatedValues
                                }
                                onChange={
                                    this.state.user.name[index] !== "undefined"
                                        ? this.updateState
                                        : this.handleUserChange
                                }
                            />
                            ,
                            <input
                                type="text"
                                name="city"
                                placeholder="city"
                                defaultValue={this.state.user.city[index]}
                                onChange={this.handleUserChange}
                            />
                        </form>
                    );
                })}

        );
    }
}

this is a sample of what I am trying to achieve, I want the form to be filled with the values present in the user state and when I change the values in the text field it should update the whole updatetoApi function so that the db can receive the new values. The problem i faced is that when I change only one values then it will basically send a post request to api with only the one updated value of the respective field and all the other values will be overwrited with null

I have a sample that i tried
https://codesandbox.io/s/nice-hodgkin-t20v0

Body:
You need a little null check in the function, calling the API:

updateToApi() {
  if(this.state.updatedValues.id &&
   this.state.updatedValues.name &&
   this.state.updatedValues.city){
     //updating the values to api using the this.state.updatedValues
  }
}


问:
Wrapping around 360 degrees with SQL query
I am fairly new with using SQL and I would like to learn how to efficiently filter a data set of ecliptic coordinates (longitude, latitude) for regions of the sky. The data set is in the southern ecliptic hemisphere (from -90 to 0 and 0 to 360) as shown below (simulated in Python with some simple numpy arange commands).

I have figured out how to filter a specific patch of the sky in python with the following code:

```<code>x = (eclong + 360 - center) % 360
ind = x > 180
x[ind] = x[ind] - 360 #converts from 0 to 360 to -180 to +180
x = -x #reverses scale where east direction is on left
</code>```

To allow data points to wrap around the South pole, I also have an additional required condition:

```<code>filtered_eclong = (x < 12/np.cos(eclat *np.pi/180)) & (-12/np.cos(eclat *np.pi/180) < x & eclat < 0)
</code>```

12 degrees is how wide the patch of sky that I want to grab is and center is a variable for the central ecliptic longitude of my desired patch of sky. The last line in the query is a correction to include objects near the southern ecliptic pole. (Note: eclat = ecliptic latitude , eclong = ecliptic longitude, both in degrees) As an example of the results I would like to get, the patch of sky I want to filter is centered on a ecliptic longitude of 315.8 degrees, seen below:

I've saved the entire simulated southern hemisphere as a csv file and uploaded the eclong and eclat values as columns in a sql database. I would like to be able to recreate the same query I performed in my Python code above. This is the closest attempt I have:

```<code>select * from coords
    where eclat < -6
    and mod(abs(eclong-315.8+360),360)-360 < 180
    and mod(abs(eclong-315.8),360) < 12/cos(radians(eclat));
</code>```

which produces this result where the filtered Python result is shown in red and the filtered sql result is shown in blue:

As shown, my query doesn't include things that wrap around from 360 degrees to 0 degrees and I'm not quite sure how to include those missing points.

I think using some combination of THEN, ELSE or CASE statements would help:

```<code>select * from Catalog
where eclat < -6
CASE
    WHEN mod(abs(eclong-315.8),360) < 12/cos(radians(eclat)) > 0 THEN 'I'm not sure what to do...'
    WHEN mod(abs(eclong-315.8),360) < 12/cos(radians(eclat)) < 360 THEN 'I'm not sure what to do...'
into myDB.filename
</code>```

Any SQL gurus out there?

答:
Though I'm not familiar with ecliptic coordinates, it sounds like you're trying to reconcile the lack of negative numbers based on your title. If that's indeed what you're going for, who cares that there aren't any negative values—let's pretend there are!

To generalize, we'll need to ensure we can safely calculate ±180 degrees from any starting longitude. With this use case, starting from 11 degrees, we could rearrange the unhelpful values by subtracting 360 from anything greater than 11 + 180 and working with the result as a helper. This way, 359 degrees would instead show up as -1, and then you can do normal math. If your starting longitude is above 180, we'd need to get the lowest values above 360. In SQL, here's a (maybe inefficient, but straightforward) way I'd create a helper column:

```<code>CASE
    WHEN center < 180 THEN CASE
                               WHEN eclong > center + 180 THEN eclong - 360
                               ELSE eclong
                           END
    WHEN center > 180 THEN CASE
                               WHEN eclong < center - 180 THEN eclong + 360
                               ELSE eclong
                           END
    ELSE eclong
END as friendly_eclong
</code>```

Body:
I am fairly new with using SQL and I would like to learn how to efficiently filter a data set of ecliptic coordinates (longitude, latitude) for regions of the sky. The data set is in the southern ecliptic hemisphere (from -90 to 0 and 0 to 360) as shown below (simulated in Python with some simple numpy arange commands).

I have figured out how to filter a specific patch of the sky in python with the following code:

x = (eclong + 360 - center) % 360
ind = x > 180
x[ind] = x[ind] - 360 #converts from 0 to 360 to -180 to +180
x = -x #reverses scale where east direction is on left

To allow data points to wrap around the South pole, I also have an additional required condition:

filtered_eclong = (x < 12/np.cos(eclat *np.pi/180)) & (-12/np.cos(eclat *np.pi/180) < x & eclat < 0)

12 degrees is how wide the patch of sky that I want to grab is and center is a variable for the central ecliptic longitude of my desired patch of sky. The last line in the query is a correction to include objects near the southern ecliptic pole. (Note: eclat = ecliptic latitude , eclong = ecliptic longitude, both in degrees) As an example of the results I would like to get, the patch of sky I want to filter is centered on a ecliptic longitude of 315.8 degrees, seen below:

I've saved the entire simulated southern hemisphere as a csv file and uploaded the eclong and eclat values as columns in a sql database. I would like to be able to recreate the same query I performed in my Python code above. This is the closest attempt I have:

select * from coords
    where eclat < -6
    and mod(abs(eclong-315.8+360),360)-360 < 180
    and mod(abs(eclong-315.8),360) < 12/cos(radians(eclat));

which produces this result where the filtered Python result is shown in red and the filtered sql result is shown in blue:

As shown, my query doesn't include things that wrap around from 360 degrees to 0 degrees and I'm not quite sure how to include those missing points.

I think using some combination of THEN, ELSE or CASE statements would help:

select * from Catalog
where eclat < -6
CASE
    WHEN mod(abs(eclong-315.8),360) < 12/cos(radians(eclat)) > 0 THEN 'I'm not sure what to do...'
    WHEN mod(abs(eclong-315.8),360) < 12/cos(radians(eclat)) < 360 THEN 'I'm not sure what to do...'
into myDB.filename

Any SQL gurus out there?

Body:
Though I'm not familiar with ecliptic coordinates, it sounds like you're trying to reconcile the lack of negative numbers based on your title. If that's indeed what you're going for, who cares that there aren't any negative values—let's pretend there are!

To generalize, we'll need to ensure we can safely calculate ±180 degrees from any starting longitude. With this use case, starting from 11 degrees, we could rearrange the unhelpful values by subtracting 360 from anything greater than 11 + 180 and working with the result as a helper. This way, 359 degrees would instead show up as -1, and then you can do normal math. If your starting longitude is above 180, we'd need to get the lowest values above 360. In SQL, here's a (maybe inefficient, but straightforward) way I'd create a helper column:

CASE
    WHEN center < 180 THEN CASE
                               WHEN eclong > center + 180 THEN eclong - 360
                               ELSE eclong
                           END
    WHEN center > 180 THEN CASE
                               WHEN eclong < center - 180 THEN eclong + 360
                               ELSE eclong
                           END
    ELSE eclong
END as friendly_eclong


问:
How can I use props, $ref and $emit in Vue-cli?
I've been learning Vuejs with Vue-cli.

I'm trying to figure out how props and $emit work.

One thing I can't figure out is that how do I handle with function related to sevral components.

All,Ongoing, Done buttons are supposed to filter list depend on each checkbox value and its color changes to green when active.

I don't know where to put filteredTodos() {} stuff which currently I added in ListTodo.vue, since those are related in both of Swichers.vue and ListTodo.vue.

My code is: Here

If somebody knows, could you tell me how?

Thanks

答:
It would be more in this spirit of vuejs to avoid refs and having state in child components.

The app contains the items and the filter and the todolist.vue binds a props to a filtered list (computed property).
The switcher takes a v-model on the filter (two way binding).
Remove all is passed as a callback property.

(Edit)

App.vue

```<code><template>
  <div>
    <h1>TODO</h1>
    <input type="text" v-model="inputTask" placeholder="Enter your task">
    <button @click="addTask">Add task</button>

    <Switchers
      v-model='filter'
      :onRemoveAll="removeAllItem"
    />
    <ListTodo :todos='filtered' :noTask='noTask' :onRemoveTask='removeTask' :onToggleStatus='toggleStatus' />
  </div>
</template>

<script>
import Switchers from "./components/Switchers";
import ListTodo from "./components/ListTodo";

export default {
  keyName: 'myTodoList',
  components: {
    Switchers,
    ListTodo,
  },

  created() {
    let keyObject =JSON.parse(localStorage.getItem(this.keyName))
    if (keyObject) {
      this.todos = keyObject;
    }
  },
  data() {
    return {
      inputTask: '',
      // filtered:'',
      filter: 'all',

      todos: [],
    };
  },
  computed: {
    filtered() {
      this.filter; this.todos;
      return this.filteredTodos()
    },
    id() { return this.todos.length+1 },
    noTask() {
      return {
        'all': 'No tasks',
        'ongoing': 'No ongoing tasks',
        'done': 'No done tasks',
      }[this.filter]
    },
  },
  methods: {
    addTask() {
      if (this.inputTask==='') {
        return
      }
      this.addTaskChild(this.inputTask);
      this.inputTask=''
    },
    addTaskChild(inputValue) {
      const todo = {id: this.id, task:inputValue, done:false}
      this.todos.push(todo)
      localStorage.setItem(this.keyName, JSON.stringify(this.todos));
      this.filter = 'all'
    },

    removeAllItem() {
      this.todos = []
      localStorage.clear();
      this.filter = 'all'
    },

    filteredTodos() {
      return this.todos.filter(todo => {
        if (this.filter === 'ongoing') {
          return !todo.done;
        } else if (this.filter === 'done') {
          return todo.done;
        } else {
          return true;
        }
      });
    },

    toggleStatus(todo) {
      todo.done =  !todo.done
      localStorage.setItem(this.keyName, JSON.stringify(this.todos));
    },

    removeTask(t) {
      this.todos = this.todos.filter(todo => todo.id !== t.id)
    },
  }
};
</script>

</code>```

ListTodo.vue

```<code><template>
  <div>
    <p>{{todos.length}} tasks left /  {{todos.length}} tasks of all</p>
    <ul>
      <li v-for="todo in todos" :class="{done:todo.done}" :key="todo.id">
      <input type="checkbox" :checked="todo.done" @click="status(todo)">
      {{ todo.task }}
      <button @click="onRemoveTask(todo)">Remove task</button>
      </li>
    </ul>
    <p v-show="todos.length===0">{{noTask}}</p>
  </div>
</template>

<script>
export default {
  props: {
    todos: {
      type: Array,
      required: true
    },
    onRemoveTask: {
      type: Function,
      required: true
    },
    onToggleStatus: {
      type: Function,
      required: true
    },
    noTask: {
      type: String,
      required: true
    }
  },
  data() {
    return {
      id: 1,
      done:false,
    };
  },
  methods: {
    status(todo) {
      this.onToggleStatus(todo)
    },
  },
};
</script>
</code>```

Switchers.vue

```<code><template>
  <div>
    <button :class="{active: filter ==='all'}" @click="set_filter('all')">All</button>
    <button :class="{active: filter ==='ongoing'}" @click="set_filter('ongoing')">Ongoing</button>
    <button :class="{active: filter ==='done'}" @click="set_filter('done')">Done</button>
    <button @click="onRemoveAll">Remove all</button>
  </div>
</template>
<script>
export default {
  props: {
    value: {
      type: String,
      required: true
    },
    onRemoveAll: {
      type: Function,
      required: true
    }
  },
  watch: {
    value: {
      handler(v) {
        if (this.filter !== v)
          this.filter = v
        },
      immediate: true
    }
  },
  data() {
    return {
      filter:'',
    };
  },
  methods: {
    set_filter(f) {
      this.filter = f
      this.$emit('input', f)
    },
  },
};
</script>
<style lang="scss" scoped>
.active {background: turquoise;}

</style>

</code>```

Idiomatic vuejs prefers reactive properties to imperative style. In this case, we would rather keep a single copy of the todo list + filter criteria (in App) and expose computed properties for the next id, filtered  list and noTask message.

Switchers is a pure controller component: it has no state and its only role is to translate user selection to call on the App model.

ListTodo is a view and only takes care of displaying the list of todos that it is given as a prop. It doesn't care about whether the list is filtered or not.

There are small style changes that could have been done too but they don't have anything to do with vuejs / emit, so I didn't do them.

Sandbox

Body:
It would be more in this spirit of vuejs to avoid refs and having state in child components.

The app contains the items and the filter and the todolist.vue binds a props to a filtered list (computed property).
The switcher takes a v-model on the filter (two way binding).
Remove all is passed as a callback property.

(Edit)

App.vue

<template>
  <div>
    <h1>TODO</h1>
    <input type="text" v-model="inputTask" placeholder="Enter your task">
    <button @click="addTask">Add task</button>

    <Switchers
      v-model='filter'
      :onRemoveAll="removeAllItem"
    />
    <ListTodo :todos='filtered' :noTask='noTask' :onRemoveTask='removeTask' :onToggleStatus='toggleStatus' />
  </div>
</template>

<script>
import Switchers from "./components/Switchers";
import ListTodo from "./components/ListTodo";

export default {
  keyName: 'myTodoList',
  components: {
    Switchers,
    ListTodo,
  },

  created() {
    let keyObject =JSON.parse(localStorage.getItem(this.keyName))
    if (keyObject) {
      this.todos = keyObject;
    }
  },
  data() {
    return {
      inputTask: '',
      // filtered:'',
      filter: 'all',

      todos: [],
    };
  },
  computed: {
    filtered() {
      this.filter; this.todos;
      return this.filteredTodos()
    },
    id() { return this.todos.length+1 },
    noTask() {
      return {
        'all': 'No tasks',
        'ongoing': 'No ongoing tasks',
        'done': 'No done tasks',
      }[this.filter]
    },
  },
  methods: {
    addTask() {
      if (this.inputTask==='') {
        return
      }
      this.addTaskChild(this.inputTask);
      this.inputTask=''
    },
    addTaskChild(inputValue) {
      const todo = {id: this.id, task:inputValue, done:false}
      this.todos.push(todo)
      localStorage.setItem(this.keyName, JSON.stringify(this.todos));
      this.filter = 'all'
    },

    removeAllItem() {
      this.todos = []
      localStorage.clear();
      this.filter = 'all'
    },

    filteredTodos() {
      return this.todos.filter(todo => {
        if (this.filter === 'ongoing') {
          return !todo.done;
        } else if (this.filter === 'done') {
          return todo.done;
        } else {
          return true;
        }
      });
    },

    toggleStatus(todo) {
      todo.done =  !todo.done
      localStorage.setItem(this.keyName, JSON.stringify(this.todos));
    },

    removeTask(t) {
      this.todos = this.todos.filter(todo => todo.id !== t.id)
    },
  }
};
</script>

ListTodo.vue

<template>
  <div>
    <p>{{todos.length}} tasks left /  {{todos.length}} tasks of all</p>
    <ul>
      <li v-for="todo in todos" :class="{done:todo.done}" :key="todo.id">
      <input type="checkbox" :checked="todo.done" @click="status(todo)">
      {{ todo.task }}
      <button @click="onRemoveTask(todo)">Remove task</button>
      </li>
    </ul>
    <p v-show="todos.length===0">{{noTask}}</p>
  </div>
</template>

<script>
export default {
  props: {
    todos: {
      type: Array,
      required: true
    },
    onRemoveTask: {
      type: Function,
      required: true
    },
    onToggleStatus: {
      type: Function,
      required: true
    },
    noTask: {
      type: String,
      required: true
    }
  },
  data() {
    return {
      id: 1,
      done:false,
    };
  },
  methods: {
    status(todo) {
      this.onToggleStatus(todo)
    },
  },
};
</script>

Switchers.vue

<template>
  <div>
    <button :class="{active: filter ==='all'}" @click="set_filter('all')">All</button>
    <button :class="{active: filter ==='ongoing'}" @click="set_filter('ongoing')">Ongoing</button>
    <button :class="{active: filter ==='done'}" @click="set_filter('done')">Done</button>
    <button @click="onRemoveAll">Remove all</button>
  </div>
</template>
<script>
export default {
  props: {
    value: {
      type: String,
      required: true
    },
    onRemoveAll: {
      type: Function,
      required: true
    }
  },
  watch: {
    value: {
      handler(v) {
        if (this.filter !== v)
          this.filter = v
        },
      immediate: true
    }
  },
  data() {
    return {
      filter:'',
    };
  },
  methods: {
    set_filter(f) {
      this.filter = f
      this.$emit('input', f)
    },
  },
};
</script>
<style lang="scss" scoped>
.active {background: turquoise;}

</style>

Idiomatic vuejs prefers reactive properties to imperative style. In this case, we would rather keep a single copy of the todo list + filter criteria (in App) and expose computed properties for the next id, filtered  list and noTask message.

Switchers is a pure controller component: it has no state and its only role is to translate user selection to call on the App model.

ListTodo is a view and only takes care of displaying the list of todos that it is given as a prop. It doesn't care about whether the list is filtered or not.

There are small style changes that could have been done too but they don't have anything to do with vuejs / emit, so I didn't do them.

Sandbox


问:
WSO2 APIM 3.0.0 : Unable to SIGN-IN from /publisher and /devportal after installing certificate
We have installed WSO2 API Manager version: 3.0.0 and it is working fine with localhost and as well as with different hostname though it shows Not secure site on address bar.
But when we install valid CA signed certificate and update deployment.toml file with primary keystore details it throws below error on server startup

```<code>TID: [-1] [] [2020-05-14 19:40:56,552]  WARN {org.wso2.carbon.apimgt.gateway.throttling.util.KeyTemplateRetriever} - Failed retrieving throttling data from remote endpoint: hostname in certificate didn't match: <localhost> != <*.example.com> OR <*.example.com> OR <example.com>. Retrying after 15 seconds...
TID: [-1] [] [2020-05-14 19:40:57,425]  WARN {org.wso2.carbon.apimgt.gateway.jwt.RevokedJWTTokensRetriever} - Failed retrieving revoked JWT token signatures from remote endpoint: hostname in certificate didn't match: <localhost> != <*.example.com> OR <*.example.com> OR <example.com>. Retrying after 15 seconds...
TID: [-1] [] [2020-05-14 19:40:57,748]  WARN {org.wso2.carbon.apimgt.gateway.throttling.util.BlockingConditionRetriever} - Failed retrieving Blocking Conditions from remote endpoint: hostname in certificate didn't match: <localhost> != <*.example.com> OR <*.example.com> OR <example.com>. Retrying after 15 seconds...
</code>```

Note- here, i have replaced actual domain name with example in above log statements due to privacy policy

After server startup, we are able to access management console and /devportal, But when we try to access /publisher or SIGN-IN from with in devportal it throws 500 error.

Without certificate and no change to keystore.primary in deployment.toml

With certificate and added keystore.primary into deployment.toml

we see the below SSL error when we try to access /Publisher or SIGN-IN from /devportal

```<code>TID: [-1234] [publisher] [2020-05-15 19:12:43,562] ERROR {org.jaggeryjs.jaggery.core.manager.WebAppManager} - org.mozilla.javascript.WrappedException: Wrapped org.jaggeryjs.scriptengine.exceptions.ScriptException: javax.net.ssl.SSLPeerUnverifiedException: SSL peer failed hostname validation for name: localhost (<<http>>/META-INF/scripts/http.js#220) org.jaggeryjs.scriptengine.exceptions.ScriptException: org.mozilla.javascript.WrappedException: Wrapped org.jaggeryjs.scriptengine.exceptions.ScriptException: javax.net.ssl.SSLPeerUnverifiedException: SSL peer failed hostname validation for name: localhost (<<http>>/META-INF/scripts/http.js#220)
    at org.jaggeryjs.scriptengine.engine.RhinoEngine.execScript(RhinoEngine.java:587)
    at org.jaggeryjs.scriptengine.engine.RhinoEngine.exec(RhinoEngine.java:289)
    at org.jaggeryjs.jaggery.core.manager.WebAppManager.exec(WebAppManager.java:589)
    at org.jaggeryjs.jaggery.core.manager.WebAppManager.execute(WebAppManager.java:508)
    at org.jaggeryjs.jaggery.core.JaggeryServlet.doGet(JaggeryServlet.java:24)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:712)
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:459)
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:352)
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:312)
    at org.jaggeryjs.jaggery.core.JaggeryFilter.doFilter(JaggeryFilter.java:76)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.wso2.carbon.ui.filters.cache.ContentTypeBasedCachePreventionFilter.doFilter(ContentTypeBasedCachePreventionFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.filters.HttpHeaderSecurityFilter.doFilter(HttpHeaderSecurityFilter.java:126)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.wso2.carbon.identity.context.rewrite.valve.TenantContextRewriteValve.invoke(TenantContextRewriteValve.java:80)
    at org.wso2.carbon.identity.authz.valve.AuthorizationValve.invoke(AuthorizationValve.java:100)
    at org.wso2.carbon.identity.auth.valve.AuthenticationValve.invoke(AuthenticationValve.java:74)
    at org.wso2.carbon.tomcat.ext.valves.CompositeValve.continueInvocation(CompositeValve.java:99)
    at org.wso2.carbon.tomcat.ext.valves.TomcatValveContainer.invokeValves(TomcatValveContainer.java:49)
    at org.wso2.carbon.tomcat.ext.valves.CompositeValve.invoke(CompositeValve.java:62)
    at org.wso2.carbon.tomcat.ext.valves.CarbonStuckThreadDetectionValve.invoke(CarbonStuckThreadDetectionValve.java:145)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:678)
    at org.wso2.carbon.tomcat.ext.valves.CarbonContextCreatorValve.invoke(CarbonContextCreatorValve.java:57)
    at org.wso2.carbon.tomcat.ext.valves.RequestCorrelationIdValve.invoke(RequestCorrelationIdValve.java:116)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:853)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1587)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: org.mozilla.javascript.WrappedException: Wrapped org.jaggeryjs.scriptengine.exceptions.ScriptException: javax.net.ssl.SSLPeerUnverifiedException: SSL peer failed hostname validation for name: localhost (<<http>>/META-INF/scripts/http.js#220)
    at org.mozilla.javascript.Context.throwAsScriptRuntimeEx(Context.java:1754)
    at org.mozilla.javascript.MemberBox.invoke(MemberBox.java:148)
    at org.mozilla.javascript.FunctionObject.call(FunctionObject.java:386)
    at org.mozilla.javascript.optimizer.OptRuntime.call1(OptRuntime.java:32)
    at org.jaggeryjs.rhino.<<http>>.META_INF.scripts.c0._c_anonymous_5(<<http>>/META-INF/scripts/http.js:220)
    at org.jaggeryjs.rhino.<<http>>.META_INF.scripts.c0.call(<<http>>/META-INF/scripts/http.js)
    at org.mozilla.javascript.optimizer.OptRuntime.callName(OptRuntime.java:63)
    at org.jaggeryjs.rhino.<<http>>.META_INF.scripts.c0._c_anonymous_7(<<http>>/META-INF/scripts/http.js:228)
    at org.jaggeryjs.rhino.<<http>>.META_INF.scripts.c0.call(<<http>>/META-INF/scripts/http.js)
    at org.mozilla.javascript.optimizer.OptRuntime.callName(OptRuntime.java:63)
    at org.jaggeryjs.rhino.publisher.services.login.c0._c_script_0(/publisher/services/login/idp.jag:35)
    at org.jaggeryjs.rhino.publisher.services.login.c0.call(/publisher/services/login/idp.jag)
    at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:394)
    at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3091)
    at org.jaggeryjs.rhino.publisher.services.login.c0.call(/publisher/services/login/idp.jag)
    at org.jaggeryjs.rhino.publisher.services.login.c0.exec(/publisher/services/login/idp.jag)
    at org.jaggeryjs.scriptengine.engine.RhinoEngine.execScript(RhinoEngine.java:583)
    ... 50 more
Caused by: org.jaggeryjs.scriptengine.exceptions.ScriptException: javax.net.ssl.SSLPeerUnverifiedException: SSL peer failed hostname validation for name: localhost
    at org.jaggeryjs.hostobjects.xhr.XMLHttpRequestHostObject.executeRequest(XMLHttpRequestHostObject.java:572)
    at org.jaggeryjs.hostobjects.xhr.XMLHttpRequestHostObject.send(XMLHttpRequestHostObject.java:549)
    at org.jaggeryjs.hostobjects.xhr.XMLHttpRequestHostObject.jsFunction_send(XMLHttpRequestHostObject.java:301)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.mozilla.javascript.MemberBox.invoke(MemberBox.java:126)
    ... 65 more
Caused by: javax.net.ssl.SSLPeerUnverifiedException: SSL peer failed hostname validation for name: localhost
    at org.opensaml.ws.soap.client.http.TLSProtocolSocketFactory.verifyHostname(TLSProtocolSocketFactory.java:233)
    at org.opensaml.ws.soap.client.http.TLSProtocolSocketFactory.createSocket(TLSProtocolSocketFactory.java:186)
    at org.apache.commons.httpclient.HttpConnection.open(HttpConnection.java:707)
    at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.open(MultiThreadedHttpConnectionManager.java:1361)
    at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:387)
    at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
    at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
    at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
    at org.jaggeryjs.hostobjects.xhr.XMLHttpRequestHostObject.executeRequest(XMLHttpRequestHostObject.java:555)
    ... 72 more
</code>```

Here is my deployment.toml file

```<code>[server]
hostname = "example.com"
node_ip = "127.0.0.1"
#offset=0
mode = "single" #single or ha
base_path = "${carbon.protocol}://${carbon.host}:${carbon.management.port}"
#discard_empty_caches = false
server_role = "default"

[super_admin]
username = "admin"
password = "admin"
create_admin_account = true

[user_store]
type = "database"

[database.apim_db]
type = "h2"
url = "jdbc:h2:./repository/database/WSO2AM_DB;AUTO_SERVER=TRUE;DB_CLOSE_ON_EXIT=FALSE"
username = "wso2carbon"
password = "wso2carbon"

[database.shared_db]
type = "h2"
url = "jdbc:h2:./repository/database/WSO2SHARED_DB;DB_CLOSE_ON_EXIT=FALSE"
username = "wso2carbon"
password = "wso2carbon"

[keystore.primary]
file_name =  "keystore.jks"
type =  "PKCS12"
password =  "mypassword"
alias =  "1"
key_password =  "mypassword"

[[apim.gateway.environment]]
name = "Production and Sandbox"
type = "hybrid"
display_in_api_console = true
description = "This is a hybrid gateway that handles both production and sandbox token traffic."
show_as_token_endpoint_url = true
service_url = "https://localhost:${mgt.transport.https.port}/services/"
username= "${admin.username}"
password= "${admin.password}"
ws_endpoint = "ws://localhost:9099"
wss_endpoint = "wss://localhost:8099"
http_endpoint = "http://localhost:${http.nio.port}"
https_endpoint = "https://localhost:${https.nio.port}"

#[apim.cache.gateway_token]
#enable = true
#expiry_time = "900s"

#[apim.cache.resource]
#enable = true
#expiry_time = "900s"

#[apim.cache.km_token]
#enable = false
#expiry_time = "15m"

#[apim.cache.recent_apis]
#enable = false

#[apim.cache.scopes]
#enable = true

#[apim.cache.publisher_roles]
#enable = true

#[apim.cache.jwt_claim]
#enable = true
#expiry_time = "15m"

#[apim.cache.tags]
#expiry_time = "2m"

#[apim.analytics]
#enable = false
#store_api_url = "https://localhost:7444"
#username = "$ref{super_admin.username}"
#password = "$ref{super_admin.password}"
#event_publisher_type = "default"
#event_publisher_impl = "org.wso2.carbon.apimgt.usage.publisher.APIMgtUsageDataBridgeDataPublisher"
#publish_response_size = true

#[[apim.analytics.url_group]]
#analytics_url =["tcp://analytics1:7611","tcp://analytics2:7611"]
#analytics_auth_url =["ssl://analytics1:7711","ssl://analytics2:7711"]
#type = "loadbalance"

#[[apim.analytics.url_group]]
#analytics_url =["tcp://analytics1:7612","tcp://analytics2:7612"]
#analytics_auth_url =["ssl://analytics1:7712","ssl://analytics2:7712"]
#type = "failover"

#[apim.key_manager]
#service_url = "https://localhost:${mgt.transport.https.port}/services/"
#username = "$ref{super_admin.username}"
#password = "$ref{super_admin.password}"
#pool.init_idle_capacity = 50
#pool.max_idle = 100
#key_validation_handler_type = "default"
#key_validation_handler_type = "custom"
#key_validation_handler_impl = "org.wso2.carbon.apimgt.keymgt.handlers.DefaultKeyValidationHandler"

#[apim.jwt]
#enable = true
#encoding = "base64" # base64,base64url
#generator_impl = "org.wso2.carbon.apimgt.keymgt.token.JWTGenerator"
#claim_dialect = "http://wso2.org/claims"
#header = "X-JWT-Assertion"
#signing_algorithm = "SHA256withRSA"
#enable_user_claims = true
#claims_extractor_impl = "org.wso2.carbon.apimgt.impl.token.DefaultClaimsRetriever"

#[apim.oauth_config]
#enable_outbound_auth_header = false
#auth_header = "Authorization"
#revoke_endpoint = "https://localhost:${https.nio.port}/revoke"
#enable_token_encryption = false
#enable_token_hashing = false

[apim.devportal]
url = "https://example.com:${mgt.transport.https.port}/devportal"
#enable_application_sharing = false
#if application_sharing_type, application_sharing_impl both defined priority goes to application_sharing_impl
#application_sharing_type = "default" #changed type, saml, default #todo: check the new config for rest api
#application_sharing_impl = "org.wso2.carbon.apimgt.impl.SAMLGroupIDExtractorImpl"
#display_multiple_versions = false
#display_deprecated_apis = false
#enable_comments = true
#enable_ratings = true
#enable_forum = true

[apim.cors]
allow_origins = "*"
allow_methods = ["GET","PUT","POST","DELETE","PATCH","OPTIONS"]
allow_headers = ["authorization","Access-Control-Allow-Origin","Content-Type","SOAPAction"]
allow_credentials = false

#[apim.throttling]
#enable_data_publishing = true
#enable_policy_deploy = true
#enable_blacklist_condition = true
#enable_persistence = true
#throttle_decision_endpoints = ["tcp://localhost:5672","tcp://localhost:5672"]

#[apim.throttling.blacklist_condition]
#start_delay = "5m"
#period = "1h"

#[apim.throttling.jms]
#start_delay = "5m"

#[apim.throttling.event_sync]
#hostName = "0.0.0.0"
#port = 11224

#[apim.throttling.event_management]
#hostName = "0.0.0.0"
#port = 10005

#[[apim.throttling.url_group]]
#traffic_manager_urls = ["tcp://localhost:9611","tcp://localhost:9611"]
#traffic_manager_auth_urls = ["ssl://localhost:9711","ssl://localhost:9711"]
#type = "loadbalance"

#[[apim.throttling.url_group]]
#traffic_manager_urls = ["tcp://localhost:9611","tcp://localhost:9611"]
#traffic_manager_auth_urls = ["ssl://localhost:9711","ssl://localhost:9711"]
#type = "failover"

#[apim.workflow]
#enable = false
#service_url = "https://localhost:9445/bpmn"
#username = "$ref{super_admin.username}"
#password = "$ref{super_admin.password}"
#callback_endpoint = "https://localhost:${mgt.transport.https.port}/api/am/admin/v0.15/workflows/update-workflow-status"
#token_endpoint = "https://localhost:${https.nio.port}/token"
#client_registration_endpoint = "https://localhost:${mgt.transport.https.port}/client-registration/v0.15/register"
#client_registration_username = "$ref{super_admin.username}"
#client_registration_password = "$ref{super_admin.password}"

#data bridge config
#[transport.receiver]
#type = "binary"
#worker_threads = 10
#session_timeout = "30m"
#keystore.file_name = "$ref{keystore.tls.file_name}"
#keystore.password = "$ref{keystore.tls.password}"
#tcp_port = 9611
#ssl_port = 9711
#ssl_receiver_thread_pool_size = 100
#tcp_receiver_thread_pool_size = 100
#ssl_enabled_protocols = ["TLSv1","TLSv1.1","TLSv1.2"]
#ciphers = ["SSL_RSA_WITH_RC4_128_MD5","SSL_RSA_WITH_RC4_128_SHA"]

#[apim.notification]
#from_address = "APIM.com"
#username = "APIM"
#password = "APIM+123"
#hostname = "localhost"
#port = 3025
#enable_start_tls = false
#enable_authentication = true

#[apim.token.revocation]
#notifier_impl = "org.wso2.carbon.apimgt.keymgt.events.TokenRevocationNotifierImpl"
#enable_realtime_notifier = true
#realtime_notifier.ttl = 5000
#enable_persistent_notifier = true
#persistent_notifier.hostname = "https://localhost:2379/v2/keys/jti/"
#persistent_notifier.ttl = 5000
#persistent_notifier.username = "root"
#persistent_notifier.password = "root"

[[event_handler]]
name="userPostSelfRegistration"
subscriptions=["POST_ADD_USER"]

[service_provider]
sp_name_regex = "^[\\sa-zA-Z0-9._-]*$"
</code>```

Below is the wrapper.conf used to start wso2 as a service. placed this file under yajsw-stable-12.14\conf

```<code>#********************************************************************
# working directory
#********************************************************************
wrapper.working.dir=${CARBON_HOME}/
# Java Main class.
# YAJSW: default is "org.rzo.yajsw.app.WrapperJVMMain"
# DO NOT SET THIS PROPERTY UNLESS YOU HAVE YOUR OWN IMPLEMENTATION
# wrapper.java.mainclass=
#********************************************************************
# tmp folder
# yajsw creates temporary files named in_.. out_.. err_.. jna..
# per default these are placed in jna.tmpdir.
# jna.tmpdir is set in setenv batch file to <yajsw>/tmp
#********************************************************************
wrapper.tmp.path = ${jna_tmpdir}
#********************************************************************
# Application main class or native executable
# One of the following properties MUST be defined
#********************************************************************
# Java Application main class
wrapper.java.app.mainclass=org.wso2.carbon.bootstrap.Bootstrap
# Log Level for console output.  (See docs for log levels)
wrapper.console.loglevel=INFO
# Log file to use for wrapper output logging.
wrapper.logfile=${wrapper_home}\/log\/wrapper.log
# Format of output for the log file.  (See docs for formats)
#wrapper.logfile.format=LPTM
# Log Level for log file output.  (See docs for log levels)
#wrapper.logfile.loglevel=INFO
# Maximum size that the log file will be allowed to grow to before
#  the log is rolled. Size is specified in bytes.  The default value
#  of 0, disables log rolling by size.  May abbreviate with the 'k' (kB) or
#  'm' (mB) suffix.  For example: 10m = 10 megabytes.
# If wrapper.logfile does not contain the string ROLLNUM it will be automatically added as suffix of the file name
wrapper.logfile.maxsize=10m
# Maximum number of rolled log files which will be allowed before old
#  files are deleted.  The default value of 0 implies no limit.
wrapper.logfile.maxfiles=10
# Title to use when running as a console
wrapper.console.title=WSO2 APIM Carbon
#********************************************************************
# Wrapper Windows Service and Posix Daemon Properties
#********************************************************************
# Name of the service
wrapper.ntservice.name=WSO2APIMCARBON
# Display name of the service
wrapper.ntservice.displayname=WSO2 APIM Carbon
# Description of the service
wrapper.ntservice.description=Carbon Kernel
#********************************************************************
# Wrapper System Tray Properties
#********************************************************************
# enable system tray
wrapper.tray = true
# TCP/IP port. If none is defined multicast discovery is used to find the port
# Set the port in case multicast is not possible.
wrapper.tray.port = 15002
#********************************************************************
# Exit Code Properties
# Restart on non zero exit code
#********************************************************************
wrapper.on_exit.0=SHUTDOWN
wrapper.on_exit.default=RESTART
#********************************************************************
# Trigger actions on console output
#********************************************************************
# On Exception show message in system tray
wrapper.filter.trigger.0=Exception
wrapper.filter.script.0=${wrapper_home}/scripts/trayMessage.gv
wrapper.filter.script.0.args=Exception
#********************************************************************
# genConfig: further Properties generated by genConfig
#********************************************************************
placeHolderSoGenPropsComeHere=
wrapper.java.command = ${JAVA_HOME}/bin/java
wrapper.java.classpath.1 = ${CARBON_HOME}/bin/*.jar
wrapper.java.classpath.2 = ${CARBON_HOME}/lib/commons-lang-*.jar
wrapper.java.classpath.3 = ${CARBON_HOME}/lib/*.jar
wrapper.app.parameter.1 = org.wso2.carbon.bootstrap.Bootstrap
wrapper.app.parameter.2 = RUN
wrapper.java.additional.1 = -Xbootclasspath/a:${CARBON_HOME}/lib/xboot/*.jar
wrapper.java.additional.2 = -Xms256m
wrapper.java.additional.3 = -Xmx1024m
wrapper.java.additional.4 = -XX:MaxPermSize=256m
wrapper.java.additional.5 = -XX:+HeapDumpOnOutOfMemoryError
wrapper.java.additional.6 = -XX:HeapDumpPath=${CARBON_HOME}/repository/logs/heap-dump.hprof
wrapper.java.additional.7 = -Dcom.sun.management.jmxremote
wrapper.java.additional.8 = -Dcarbon.registry.root=\/
wrapper.java.additional.9 = -Dcarbon.home=${CARBON_HOME}
wrapper.java.additional.10 = -Dwso2.server.standalone=true
wrapper.java.additional.11 = -Djava.command=${JAVA_HOME}/bin/java
wrapper.java.additional.12 = -Djava.io.tmpdir=${CARBON_HOME}/tmp
wrapper.java.additional.13 = -Dcatalina.base=${CARBON_HOME}/lib/tomcat
wrapper.java.additional.14 = -Djava.util.logging.config.file=${CARBON_HOME}/repository/conf/etc/logging-bridge.properties
wrapper.java.additional.15 = -Dcarbon.config.dir.path=${CARBON_HOME}/repository/conf
wrapper.java.additional.16 = -Dcarbon.logs.path=${CARBON_HOME}/repository/logs
wrapper.java.additional.17 = -Dcomponents.repo=${CARBON_HOME}/repository/components/plugins
wrapper.java.additional.18 = -Dconf.location=${CARBON_HOME}/repository/conf
wrapper.java.additional.19 = -Dcom.atomikos.icatch.file=${CARBON_HOME}/lib/transactions.properties
wrapper.java.additional.20 = -Dcom.atomikos.icatch.hide_init_file_path=true
wrapper.java.additional.21 = -Dorg.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER=true
wrapper.java.additional.22 = -Dcom.sun.jndi.ldap.connect.pool.authentication=simple
wrapper.java.additional.23 = -Dcom.sun.jndi.ldap.connect.pool.timeout=3000
wrapper.java.additional.24 = -Dorg.terracotta.quartz.skipUpdateCheck=true
wrapper.java.additional.25 = -Dorg.apache.jasper.compiler.Parser.STRICT_QUOTE_ESCAPING=false
wrapper.java.additional.26 = -Dfile.encoding=UTF8
wrapper.java.additional.27 = -DworkerNode=false
wrapper.java.additional.28 = -Dhttpclient.hostnameVerifier=DefaultAndLocalhost
wrapper.java.additional.29 = -Dcarbon.new.config.dir.path=${CARBON_HOME}/repository/resources/conf
</code>```

答: During login APIM makes internal API calls. This error occurs when hostname 'localhost' is used for the API calls but the truststore doesn't have a valid certificate for 'localhost'. Changing the hostname used in the API calls to the hostname configured in the deployment.yaml should resolve this. The internal API calls can be found in the jaggery files in the [HOME]/repository/deployment/server/jaggeryapps/[DEVPORTAL/PUBLISHER]/services directory. Or else add a SAN to the cert for localhost.

Body:
We have installed WSO2 API Manager version: 3.0.0 and it is working fine with localhost and as well as with different hostname though it shows Not secure site on address bar.
But when we install valid CA signed certificate and update deployment.toml file with primary keystore details it throws below error on server startup

TID: [-1] [] [2020-05-14 19:40:56,552]  WARN {org.wso2.carbon.apimgt.gateway.throttling.util.KeyTemplateRetriever} - Failed retrieving throttling data from remote endpoint: hostname in certificate didn't match: <localhost> != <*.example.com> OR <*.example.com> OR <example.com>. Retrying after 15 seconds...
TID: [-1] [] [2020-05-14 19:40:57,425]  WARN {org.wso2.carbon.apimgt.gateway.jwt.RevokedJWTTokensRetriever} - Failed retrieving revoked JWT token signatures from remote endpoint: hostname in certificate didn't match: <localhost> != <*.example.com> OR <*.example.com> OR <example.com>. Retrying after 15 seconds...
TID: [-1] [] [2020-05-14 19:40:57,748]  WARN {org.wso2.carbon.apimgt.gateway.throttling.util.BlockingConditionRetriever} - Failed retrieving Blocking Conditions from remote endpoint: hostname in certificate didn't match: <localhost> != <*.example.com> OR <*.example.com> OR <example.com>. Retrying after 15 seconds...

Note- here, i have replaced actual domain name with example in above log statements due to privacy policy

After server startup, we are able to access management console and /devportal, But when we try to access /publisher or SIGN-IN from with in devportal it throws 500 error.

Without certificate and no change to keystore.primary in deployment.toml

With certificate and added keystore.primary into deployment.toml

we see the below SSL error when we try to access /Publisher or SIGN-IN from /devportal

TID: [-1234] [publisher] [2020-05-15 19:12:43,562] ERROR {org.jaggeryjs.jaggery.core.manager.WebAppManager} - org.mozilla.javascript.WrappedException: Wrapped org.jaggeryjs.scriptengine.exceptions.ScriptException: javax.net.ssl.SSLPeerUnverifiedException: SSL peer failed hostname validation for name: localhost (<<http>>/META-INF/scripts/http.js#220) org.jaggeryjs.scriptengine.exceptions.ScriptException: org.mozilla.javascript.WrappedException: Wrapped org.jaggeryjs.scriptengine.exceptions.ScriptException: javax.net.ssl.SSLPeerUnverifiedException: SSL peer failed hostname validation for name: localhost (<<http>>/META-INF/scripts/http.js#220)
    at org.jaggeryjs.scriptengine.engine.RhinoEngine.execScript(RhinoEngine.java:587)
    at org.jaggeryjs.scriptengine.engine.RhinoEngine.exec(RhinoEngine.java:289)
    at org.jaggeryjs.jaggery.core.manager.WebAppManager.exec(WebAppManager.java:589)
    at org.jaggeryjs.jaggery.core.manager.WebAppManager.execute(WebAppManager.java:508)
    at org.jaggeryjs.jaggery.core.JaggeryServlet.doGet(JaggeryServlet.java:24)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:712)
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:459)
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:352)
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:312)
    at org.jaggeryjs.jaggery.core.JaggeryFilter.doFilter(JaggeryFilter.java:76)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.wso2.carbon.ui.filters.cache.ContentTypeBasedCachePreventionFilter.doFilter(ContentTypeBasedCachePreventionFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.filters.HttpHeaderSecurityFilter.doFilter(HttpHeaderSecurityFilter.java:126)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.wso2.carbon.identity.context.rewrite.valve.TenantContextRewriteValve.invoke(TenantContextRewriteValve.java:80)
    at org.wso2.carbon.identity.authz.valve.AuthorizationValve.invoke(AuthorizationValve.java:100)
    at org.wso2.carbon.identity.auth.valve.AuthenticationValve.invoke(AuthenticationValve.java:74)
    at org.wso2.carbon.tomcat.ext.valves.CompositeValve.continueInvocation(CompositeValve.java:99)
    at org.wso2.carbon.tomcat.ext.valves.TomcatValveContainer.invokeValves(TomcatValveContainer.java:49)
    at org.wso2.carbon.tomcat.ext.valves.CompositeValve.invoke(CompositeValve.java:62)
    at org.wso2.carbon.tomcat.ext.valves.CarbonStuckThreadDetectionValve.invoke(CarbonStuckThreadDetectionValve.java:145)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:678)
    at org.wso2.carbon.tomcat.ext.valves.CarbonContextCreatorValve.invoke(CarbonContextCreatorValve.java:57)
    at org.wso2.carbon.tomcat.ext.valves.RequestCorrelationIdValve.invoke(RequestCorrelationIdValve.java:116)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:853)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1587)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: org.mozilla.javascript.WrappedException: Wrapped org.jaggeryjs.scriptengine.exceptions.ScriptException: javax.net.ssl.SSLPeerUnverifiedException: SSL peer failed hostname validation for name: localhost (<<http>>/META-INF/scripts/http.js#220)
    at org.mozilla.javascript.Context.throwAsScriptRuntimeEx(Context.java:1754)
    at org.mozilla.javascript.MemberBox.invoke(MemberBox.java:148)
    at org.mozilla.javascript.FunctionObject.call(FunctionObject.java:386)
    at org.mozilla.javascript.optimizer.OptRuntime.call1(OptRuntime.java:32)
    at org.jaggeryjs.rhino.<<http>>.META_INF.scripts.c0._c_anonymous_5(<<http>>/META-INF/scripts/http.js:220)
    at org.jaggeryjs.rhino.<<http>>.META_INF.scripts.c0.call(<<http>>/META-INF/scripts/http.js)
    at org.mozilla.javascript.optimizer.OptRuntime.callName(OptRuntime.java:63)
    at org.jaggeryjs.rhino.<<http>>.META_INF.scripts.c0._c_anonymous_7(<<http>>/META-INF/scripts/http.js:228)
    at org.jaggeryjs.rhino.<<http>>.META_INF.scripts.c0.call(<<http>>/META-INF/scripts/http.js)
    at org.mozilla.javascript.optimizer.OptRuntime.callName(OptRuntime.java:63)
    at org.jaggeryjs.rhino.publisher.services.login.c0._c_script_0(/publisher/services/login/idp.jag:35)
    at org.jaggeryjs.rhino.publisher.services.login.c0.call(/publisher/services/login/idp.jag)
    at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:394)
    at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3091)
    at org.jaggeryjs.rhino.publisher.services.login.c0.call(/publisher/services/login/idp.jag)
    at org.jaggeryjs.rhino.publisher.services.login.c0.exec(/publisher/services/login/idp.jag)
    at org.jaggeryjs.scriptengine.engine.RhinoEngine.execScript(RhinoEngine.java:583)
    ... 50 more
Caused by: org.jaggeryjs.scriptengine.exceptions.ScriptException: javax.net.ssl.SSLPeerUnverifiedException: SSL peer failed hostname validation for name: localhost
    at org.jaggeryjs.hostobjects.xhr.XMLHttpRequestHostObject.executeRequest(XMLHttpRequestHostObject.java:572)
    at org.jaggeryjs.hostobjects.xhr.XMLHttpRequestHostObject.send(XMLHttpRequestHostObject.java:549)
    at org.jaggeryjs.hostobjects.xhr.XMLHttpRequestHostObject.jsFunction_send(XMLHttpRequestHostObject.java:301)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.mozilla.javascript.MemberBox.invoke(MemberBox.java:126)
    ... 65 more
Caused by: javax.net.ssl.SSLPeerUnverifiedException: SSL peer failed hostname validation for name: localhost
    at org.opensaml.ws.soap.client.http.TLSProtocolSocketFactory.verifyHostname(TLSProtocolSocketFactory.java:233)
    at org.opensaml.ws.soap.client.http.TLSProtocolSocketFactory.createSocket(TLSProtocolSocketFactory.java:186)
    at org.apache.commons.httpclient.HttpConnection.open(HttpConnection.java:707)
    at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.open(MultiThreadedHttpConnectionManager.java:1361)
    at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:387)
    at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
    at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
    at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
    at org.jaggeryjs.hostobjects.xhr.XMLHttpRequestHostObject.executeRequest(XMLHttpRequestHostObject.java:555)
    ... 72 more

Here is my deployment.toml file

[server]
hostname = "example.com"
node_ip = "127.0.0.1"
#offset=0
mode = "single" #single or ha
base_path = "${carbon.protocol}://${carbon.host}:${carbon.management.port}"
#discard_empty_caches = false
server_role = "default"

[super_admin]
username = "admin"
password = "admin"
create_admin_account = true

[user_store]
type = "database"

[database.apim_db]
type = "h2"
url = "jdbc:h2:./repository/database/WSO2AM_DB;AUTO_SERVER=TRUE;DB_CLOSE_ON_EXIT=FALSE"
username = "wso2carbon"
password = "wso2carbon"

[database.shared_db]
type = "h2"
url = "jdbc:h2:./repository/database/WSO2SHARED_DB;DB_CLOSE_ON_EXIT=FALSE"
username = "wso2carbon"
password = "wso2carbon"

[keystore.primary]
file_name =  "keystore.jks"
type =  "PKCS12"
password =  "mypassword"
alias =  "1"
key_password =  "mypassword"

[[apim.gateway.environment]]
name = "Production and Sandbox"
type = "hybrid"
display_in_api_console = true
description = "This is a hybrid gateway that handles both production and sandbox token traffic."
show_as_token_endpoint_url = true
service_url = "https://localhost:${mgt.transport.https.port}/services/"
username= "${admin.username}"
password= "${admin.password}"
ws_endpoint = "ws://localhost:9099"
wss_endpoint = "wss://localhost:8099"
http_endpoint = "http://localhost:${http.nio.port}"
https_endpoint = "https://localhost:${https.nio.port}"

#[apim.cache.gateway_token]
#enable = true
#expiry_time = "900s"

#[apim.cache.resource]
#enable = true
#expiry_time = "900s"

#[apim.cache.km_token]
#enable = false
#expiry_time = "15m"

#[apim.cache.recent_apis]
#enable = false

#[apim.cache.scopes]
#enable = true

#[apim.cache.publisher_roles]
#enable = true

#[apim.cache.jwt_claim]
#enable = true
#expiry_time = "15m"

#[apim.cache.tags]
#expiry_time = "2m"

#[apim.analytics]
#enable = false
#store_api_url = "https://localhost:7444"
#username = "$ref{super_admin.username}"
#password = "$ref{super_admin.password}"
#event_publisher_type = "default"
#event_publisher_impl = "org.wso2.carbon.apimgt.usage.publisher.APIMgtUsageDataBridgeDataPublisher"
#publish_response_size = true

#[[apim.analytics.url_group]]
#analytics_url =["tcp://analytics1:7611","tcp://analytics2:7611"]
#analytics_auth_url =["ssl://analytics1:7711","ssl://analytics2:7711"]
#type = "loadbalance"

#[[apim.analytics.url_group]]
#analytics_url =["tcp://analytics1:7612","tcp://analytics2:7612"]
#analytics_auth_url =["ssl://analytics1:7712","ssl://analytics2:7712"]
#type = "failover"

#[apim.key_manager]
#service_url = "https://localhost:${mgt.transport.https.port}/services/"
#username = "$ref{super_admin.username}"
#password = "$ref{super_admin.password}"
#pool.init_idle_capacity = 50
#pool.max_idle = 100
#key_validation_handler_type = "default"
#key_validation_handler_type = "custom"
#key_validation_handler_impl = "org.wso2.carbon.apimgt.keymgt.handlers.DefaultKeyValidationHandler"

#[apim.jwt]
#enable = true
#encoding = "base64" # base64,base64url
#generator_impl = "org.wso2.carbon.apimgt.keymgt.token.JWTGenerator"
#claim_dialect = "http://wso2.org/claims"
#header = "X-JWT-Assertion"
#signing_algorithm = "SHA256withRSA"
#enable_user_claims = true
#claims_extractor_impl = "org.wso2.carbon.apimgt.impl.token.DefaultClaimsRetriever"

#[apim.oauth_config]
#enable_outbound_auth_header = false
#auth_header = "Authorization"
#revoke_endpoint = "https://localhost:${https.nio.port}/revoke"
#enable_token_encryption = false
#enable_token_hashing = false

[apim.devportal]
url = "https://example.com:${mgt.transport.https.port}/devportal"
#enable_application_sharing = false
#if application_sharing_type, application_sharing_impl both defined priority goes to application_sharing_impl
#application_sharing_type = "default" #changed type, saml, default #todo: check the new config for rest api
#application_sharing_impl = "org.wso2.carbon.apimgt.impl.SAMLGroupIDExtractorImpl"
#display_multiple_versions = false
#display_deprecated_apis = false
#enable_comments = true
#enable_ratings = true
#enable_forum = true

[apim.cors]
allow_origins = "*"
allow_methods = ["GET","PUT","POST","DELETE","PATCH","OPTIONS"]
allow_headers = ["authorization","Access-Control-Allow-Origin","Content-Type","SOAPAction"]
allow_credentials = false

#[apim.throttling]
#enable_data_publishing = true
#enable_policy_deploy = true
#enable_blacklist_condition = true
#enable_persistence = true
#throttle_decision_endpoints = ["tcp://localhost:5672","tcp://localhost:5672"]

#[apim.throttling.blacklist_condition]
#start_delay = "5m"
#period = "1h"

#[apim.throttling.jms]
#start_delay = "5m"

#[apim.throttling.event_sync]
#hostName = "0.0.0.0"
#port = 11224

#[apim.throttling.event_management]
#hostName = "0.0.0.0"
#port = 10005

#[[apim.throttling.url_group]]
#traffic_manager_urls = ["tcp://localhost:9611","tcp://localhost:9611"]
#traffic_manager_auth_urls = ["ssl://localhost:9711","ssl://localhost:9711"]
#type = "loadbalance"

#[[apim.throttling.url_group]]
#traffic_manager_urls = ["tcp://localhost:9611","tcp://localhost:9611"]
#traffic_manager_auth_urls = ["ssl://localhost:9711","ssl://localhost:9711"]
#type = "failover"

#[apim.workflow]
#enable = false
#service_url = "https://localhost:9445/bpmn"
#username = "$ref{super_admin.username}"
#password = "$ref{super_admin.password}"
#callback_endpoint = "https://localhost:${mgt.transport.https.port}/api/am/admin/v0.15/workflows/update-workflow-status"
#token_endpoint = "https://localhost:${https.nio.port}/token"
#client_registration_endpoint = "https://localhost:${mgt.transport.https.port}/client-registration/v0.15/register"
#client_registration_username = "$ref{super_admin.username}"
#client_registration_password = "$ref{super_admin.password}"

#data bridge config
#[transport.receiver]
#type = "binary"
#worker_threads = 10
#session_timeout = "30m"
#keystore.file_name = "$ref{keystore.tls.file_name}"
#keystore.password = "$ref{keystore.tls.password}"
#tcp_port = 9611
#ssl_port = 9711
#ssl_receiver_thread_pool_size = 100
#tcp_receiver_thread_pool_size = 100
#ssl_enabled_protocols = ["TLSv1","TLSv1.1","TLSv1.2"]
#ciphers = ["SSL_RSA_WITH_RC4_128_MD5","SSL_RSA_WITH_RC4_128_SHA"]

#[apim.notification]
#from_address = "APIM.com"
#username = "APIM"
#password = "APIM+123"
#hostname = "localhost"
#port = 3025
#enable_start_tls = false
#enable_authentication = true

#[apim.token.revocation]
#notifier_impl = "org.wso2.carbon.apimgt.keymgt.events.TokenRevocationNotifierImpl"
#enable_realtime_notifier = true
#realtime_notifier.ttl = 5000
#enable_persistent_notifier = true
#persistent_notifier.hostname = "https://localhost:2379/v2/keys/jti/"
#persistent_notifier.ttl = 5000
#persistent_notifier.username = "root"
#persistent_notifier.password = "root"

[[event_handler]]
name="userPostSelfRegistration"
subscriptions=["POST_ADD_USER"]

[service_provider]
sp_name_regex = "^[\\sa-zA-Z0-9._-]*$"

Below is the wrapper.conf used to start wso2 as a service. placed this file under yajsw-stable-12.14\conf

#********************************************************************
# working directory
#********************************************************************
wrapper.working.dir=${CARBON_HOME}/
# Java Main class.
# YAJSW: default is "org.rzo.yajsw.app.WrapperJVMMain"
# DO NOT SET THIS PROPERTY UNLESS YOU HAVE YOUR OWN IMPLEMENTATION
# wrapper.java.mainclass=
#********************************************************************
# tmp folder
# yajsw creates temporary files named in_.. out_.. err_.. jna..
# per default these are placed in jna.tmpdir.
# jna.tmpdir is set in setenv batch file to <yajsw>/tmp
#********************************************************************
wrapper.tmp.path = ${jna_tmpdir}
#********************************************************************
# Application main class or native executable
# One of the following properties MUST be defined
#********************************************************************
# Java Application main class
wrapper.java.app.mainclass=org.wso2.carbon.bootstrap.Bootstrap
# Log Level for console output.  (See docs for log levels)
wrapper.console.loglevel=INFO
# Log file to use for wrapper output logging.
wrapper.logfile=${wrapper_home}\/log\/wrapper.log
# Format of output for the log file.  (See docs for formats)
#wrapper.logfile.format=LPTM
# Log Level for log file output.  (See docs for log levels)
#wrapper.logfile.loglevel=INFO
# Maximum size that the log file will be allowed to grow to before
#  the log is rolled. Size is specified in bytes.  The default value
#  of 0, disables log rolling by size.  May abbreviate with the 'k' (kB) or
#  'm' (mB) suffix.  For example: 10m = 10 megabytes.
# If wrapper.logfile does not contain the string ROLLNUM it will be automatically added as suffix of the file name
wrapper.logfile.maxsize=10m
# Maximum number of rolled log files which will be allowed before old
#  files are deleted.  The default value of 0 implies no limit.
wrapper.logfile.maxfiles=10
# Title to use when running as a console
wrapper.console.title=WSO2 APIM Carbon
#********************************************************************
# Wrapper Windows Service and Posix Daemon Properties
#********************************************************************
# Name of the service
wrapper.ntservice.name=WSO2APIMCARBON
# Display name of the service
wrapper.ntservice.displayname=WSO2 APIM Carbon
# Description of the service
wrapper.ntservice.description=Carbon Kernel
#********************************************************************
# Wrapper System Tray Properties
#********************************************************************
# enable system tray
wrapper.tray = true
# TCP/IP port. If none is defined multicast discovery is used to find the port
# Set the port in case multicast is not possible.
wrapper.tray.port = 15002
#********************************************************************
# Exit Code Properties
# Restart on non zero exit code
#********************************************************************
wrapper.on_exit.0=SHUTDOWN
wrapper.on_exit.default=RESTART
#********************************************************************
# Trigger actions on console output
#********************************************************************
# On Exception show message in system tray
wrapper.filter.trigger.0=Exception
wrapper.filter.script.0=${wrapper_home}/scripts/trayMessage.gv
wrapper.filter.script.0.args=Exception
#********************************************************************
# genConfig: further Properties generated by genConfig
#********************************************************************
placeHolderSoGenPropsComeHere=
wrapper.java.command = ${JAVA_HOME}/bin/java
wrapper.java.classpath.1 = ${CARBON_HOME}/bin/*.jar
wrapper.java.classpath.2 = ${CARBON_HOME}/lib/commons-lang-*.jar
wrapper.java.classpath.3 = ${CARBON_HOME}/lib/*.jar
wrapper.app.parameter.1 = org.wso2.carbon.bootstrap.Bootstrap
wrapper.app.parameter.2 = RUN
wrapper.java.additional.1 = -Xbootclasspath/a:${CARBON_HOME}/lib/xboot/*.jar
wrapper.java.additional.2 = -Xms256m
wrapper.java.additional.3 = -Xmx1024m
wrapper.java.additional.4 = -XX:MaxPermSize=256m
wrapper.java.additional.5 = -XX:+HeapDumpOnOutOfMemoryError
wrapper.java.additional.6 = -XX:HeapDumpPath=${CARBON_HOME}/repository/logs/heap-dump.hprof
wrapper.java.additional.7 = -Dcom.sun.management.jmxremote
wrapper.java.additional.8 = -Dcarbon.registry.root=\/
wrapper.java.additional.9 = -Dcarbon.home=${CARBON_HOME}
wrapper.java.additional.10 = -Dwso2.server.standalone=true
wrapper.java.additional.11 = -Djava.command=${JAVA_HOME}/bin/java
wrapper.java.additional.12 = -Djava.io.tmpdir=${CARBON_HOME}/tmp
wrapper.java.additional.13 = -Dcatalina.base=${CARBON_HOME}/lib/tomcat
wrapper.java.additional.14 = -Djava.util.logging.config.file=${CARBON_HOME}/repository/conf/etc/logging-bridge.properties
wrapper.java.additional.15 = -Dcarbon.config.dir.path=${CARBON_HOME}/repository/conf
wrapper.java.additional.16 = -Dcarbon.logs.path=${CARBON_HOME}/repository/logs
wrapper.java.additional.17 = -Dcomponents.repo=${CARBON_HOME}/repository/components/plugins
wrapper.java.additional.18 = -Dconf.location=${CARBON_HOME}/repository/conf
wrapper.java.additional.19 = -Dcom.atomikos.icatch.file=${CARBON_HOME}/lib/transactions.properties
wrapper.java.additional.20 = -Dcom.atomikos.icatch.hide_init_file_path=true
wrapper.java.additional.21 = -Dorg.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER=true
wrapper.java.additional.22 = -Dcom.sun.jndi.ldap.connect.pool.authentication=simple
wrapper.java.additional.23 = -Dcom.sun.jndi.ldap.connect.pool.timeout=3000
wrapper.java.additional.24 = -Dorg.terracotta.quartz.skipUpdateCheck=true
wrapper.java.additional.25 = -Dorg.apache.jasper.compiler.Parser.STRICT_QUOTE_ESCAPING=false
wrapper.java.additional.26 = -Dfile.encoding=UTF8
wrapper.java.additional.27 = -DworkerNode=false
wrapper.java.additional.28 = -Dhttpclient.hostnameVerifier=DefaultAndLocalhost
wrapper.java.additional.29 = -Dcarbon.new.config.dir.path=${CARBON_HOME}/repository/resources/conf


问:
Kubernetes certificate always disappear after few hours
I am new to kubernetes. I created a certificate in kubernetes for my validation webhook.
After approving the certificate, and checking if it is still there after few hours, by running

```<code>kubectl -n mynamespace get csr
</code>```

However, it shows no resources found in the namespace. But if the certificate is newly created
and run the same command above it shows the certificate.

Is this an expected behavior? where does the certificate go?

Please help. :(

答:
This is an expected behavior for security reasons. You should download the certificate using below command and keep it safe.

```<code>kubectl get csr my-svc.my-namespace -o jsonpath='{.status.certificate}' \
    | base64 --decode > server.crt
</code>```

https://kubernetes.io/docs/tasks/tls/managing-tls-in-a-cluster/#download-the-certificate-and-use-it

Body:
I am new to kubernetes. I created a certificate in kubernetes for my validation webhook.
After approving the certificate, and checking if it is still there after few hours, by running

kubectl -n mynamespace get csr

However, it shows no resources found in the namespace. But if the certificate is newly created
and run the same command above it shows the certificate.

Is this an expected behavior? where does the certificate go?

Please help. :(

Body:
This is an expected behavior for security reasons. You should download the certificate using below command and keep it safe.

kubectl get csr my-svc.my-namespace -o jsonpath='{.status.certificate}' \
    | base64 --decode > server.crt

https://kubernetes.io/docs/tasks/tls/managing-tls-in-a-cluster/#download-the-certificate-and-use-it


问:
Running a long rails console or rake task on Heroku
My rails application is hosted on Heroku. I'm trying to process data in my postgresql DB with a straightforward loop

```<code>  DocumentText.all.each do |t|
    if is_number? t.src
      puts t.src
      t.targ = t.src
      t.save
    end
  end
</code>```

The problem I have is my rails console will exit after running through some of my records (not all of them.) I have tried this as a rake task but same problem.

Why is this happening and what are my options?

答:
@Pradeep Agrawal's answer lead me to the solution using activerecord-import gem (his answer was copy and pasted from the gem and contained bugs).</p>

```<code>documents = []
DocumentText.all.each do |t|
  if is_number?(t.src)
    documents << t
  end
end

DocumentText.import(documents, on_duplicate_key_update: {
  conflict_target: [:id], columns: {targ: :src}
})
</code>```

Body:
My rails application is hosted on Heroku. I'm trying to process data in my postgresql DB with a straightforward loop

  DocumentText.all.each do |t|
    if is_number? t.src
      puts t.src
      t.targ = t.src
      t.save
    end
  end

The problem I have is my rails console will exit after running through some of my records (not all of them.) I have tried this as a rake task but same problem.

Why is this happening and what are my options?

Body:
@Pradeep Agrawal's answer lead me to the solution using activerecord-import gem (his answer was copy and pasted from the gem and contained bugs).

documents = []
DocumentText.all.each do |t|
  if is_number?(t.src)
    documents << t
  end
end

DocumentText.import(documents, on_duplicate_key_update: {
  conflict_target: [:id], columns: {targ: :src}
})


问:
How to call a function after closing a popover?
I hope someone can give a beginner some guidance, my problem is this:

I have a popover window
I open that popover with a segue from the mainViewController
I want to trigger a function in the mainViewController when the popover is closed
Inside the popover I have a button to close the popover with the following code:

```<code>@IBAction func closeButton(_ sender: Any) {

        dismiss(animated: true, completion: {checkIfPopoverDismissed()}) // I want to trigger this function in the mainView
    }
</code>```

In the mainViewController I have the following function, that I want to be triggered by the closure of the above popover

```<code> func checkIfPopoverDismissed()
    {
      print("the function is triggered")
    }
</code>```

So with the above I get:

```<code> Use of unresolved identifier 'checkIfPopoverDismissed'
</code>```

Because obviously checkIfPopoverDismissed() is in the mainViewController and does not exist in the popover view.

Any idea how I can make this work simply?

答:
Ideally, you should write a delegate to call a method from the alert or pop-over View controller to the main view controller.

Here is the example of the code:

```<code>// Create a protocol with set of methods
protocol AlertVCDelegate: class {
    func checkIfPopoverDismissed()
}

class AlertVC: UIViewController {
    // Create var to hold the delegate
    // Make it weak to avoid reference cycle
    weak var delegate: AlertVCDelegate!

    @IBAction func closeButton(_ sender: Any) {

        dismiss(animated: true, completion: {
            // Trigger the function on the main view controller
            // through delegation
            self.delegate.checkIfPopoverDismissed()
        })
    }
}

// Conform to the Alert delegte
class MainViewController: UIViewController, AlertVCDelegate {
    let alertControllerObj = AlertVC()

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        // Set the delegate
        // Not necessary to do it from viewWillAppear
        // Set the delegate wherever you create a instance for pop-over
        alertControllerObj.delegate = self
    }

   // Implement the method defined in the protocol
   func checkIfPopoverDismissed()
   {
     print("the function is triggered")
   }
}
</code>```

As you are a beginner and If you want to know more about the delegates here is a nice and simple blog:
https://medium.com/@astitv96/passing-data-between-view-controllers-using-delegate-and-protocol-ios-swift-4-beginners-e32828862d3f

Body:
I hope someone can give a beginner some guidance, my problem is this:

I have a popover window
I open that popover with a segue from the mainViewController
I want to trigger a function in the mainViewController when the popover is closed
Inside the popover I have a button to close the popover with the following code:

@IBAction func closeButton(_ sender: Any) {

        dismiss(animated: true, completion: {checkIfPopoverDismissed()}) // I want to trigger this function in the mainView
    }

In the mainViewController I have the following function, that I want to be triggered by the closure of the above popover

 func checkIfPopoverDismissed()
    {
      print("the function is triggered")
    }

So with the above I get:

 Use of unresolved identifier 'checkIfPopoverDismissed'

Because obviously checkIfPopoverDismissed() is in the mainViewController and does not exist in the popover view.

Any idea how I can make this work simply?

Body:
Ideally, you should write a delegate to call a method from the alert or pop-over View controller to the main view controller.

Here is the example of the code:

// Create a protocol with set of methods
protocol AlertVCDelegate: class {
    func checkIfPopoverDismissed()
}

class AlertVC: UIViewController {
    // Create var to hold the delegate
    // Make it weak to avoid reference cycle
    weak var delegate: AlertVCDelegate!

    @IBAction func closeButton(_ sender: Any) {

        dismiss(animated: true, completion: {
            // Trigger the function on the main view controller
            // through delegation
            self.delegate.checkIfPopoverDismissed()
        })
    }
}

// Conform to the Alert delegte
class MainViewController: UIViewController, AlertVCDelegate {
    let alertControllerObj = AlertVC()

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        // Set the delegate
        // Not necessary to do it from viewWillAppear
        // Set the delegate wherever you create a instance for pop-over
        alertControllerObj.delegate = self
    }

   // Implement the method defined in the protocol
   func checkIfPopoverDismissed()
   {
     print("the function is triggered")
   }
}

As you are a beginner and If you want to know more about the delegates here is a nice and simple blog:
https://medium.com/@astitv96/passing-data-between-view-controllers-using-delegate-and-protocol-ios-swift-4-beginners-e32828862d3f


问:
Increasing clickable area of ImageView
I have created a RelativeLayout shown below as part of a toolbar. The layout consists of two images and a thin line below the images. For the two images I have increased the width because then the clickable area is wider. A screenshot (Android Studio) how it looks like is shown at the bottom.

The problem now is that I can't control the size of the image (the image is just placed in the center). How can I fix the actual size of the image to 25 x 25 dp and still extend the clickable area to the left and right of the image by let's say 70 dp and at the bottom and top of the image by 10 dp?

```<code><RelativeLayout  xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/keyboard_toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:orientation="horizontal">

    <View
        android:id="@+id/keyboard_toolbar_line"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_below="@id/privacyButton"
        android:layout_marginBottom="5dp"
        android:background="#c0c0c0"/>

    <ImageView
        android:id="@+id/privacyButton"
        android:layout_width="100dp"
        android:layout_alignParentStart="true"
        android:layout_height="35dp"
        android:scaleType="center"
        android:layout_marginStart="30dp"
        android:src="@drawable/research_ic_lock_open_dark" />

    <ImageView
        android:id="@+id/ratingButton"
        android:layout_width="100dp"
        android:layout_alignParentEnd="true"
        android:layout_height="35dp"
        android:scaleType="center"
        android:layout_marginEnd="30dp"
        android:src="@drawable/ic_star" />

</RelativeLayout >
</code>```

答:
If I'm not mistaken, this is your solution.

You first put a parent layout and then put the ImageView inside it.
Then onclicklistener on the parent.

```<code> <RelativeLayout  xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/keyboard_toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:orientation="horizontal">

        <View
            android:id="@+id/keyboard_toolbar_line"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_below="@id/privacyButton"
            android:layout_marginBottom="5dp"
            android:background="#c0c0c0"/>

        <RelativeLayout
            android:layout_width="100dp"
            android:layout_height="35dp">
            <ImageView
                android:id="@+id/privacyButton"
                android:layout_width="35dp"
                android:layout_alignParentStart="true"
                android:layout_height="35dp"
                android:scaleType="center"
                android:layout_marginStart="30dp"
                android:src="@drawable/research_ic_lock_open_dark" />
        </RelativeLayout>
    <RelativeLayout
        android:layout_width="100dp"
        android:layout_height="35dp">

        <ImageView
            android:id="@+id/ratingButton"
            android:layout_width="35dp"
            android:layout_alignParentEnd="true"
            android:layout_height="35dp"
            android:scaleType="center"
            android:layout_marginEnd="30dp"
            android:src="@drawable/ic_star" />
    </RelativeLayout>

    </RelativeLayout>
</code>```

Title: Increasing clickable area of ImageView

Body:
I have created a RelativeLayout shown below as part of a toolbar. The layout consists of two images and a thin line below the images. For the two images I have increased the width because then the clickable area is wider. A screenshot (Android Studio) how it looks like is shown at the bottom.

The problem now is that I can't control the size of the image (the image is just placed in the center). How can I fix the actual size of the image to 25 x 25 dp and still extend the clickable area to the left and right of the image by let's say 70 dp and at the bottom and top of the image by 10 dp?

<RelativeLayout  xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/keyboard_toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:orientation="horizontal">

    <View
        android:id="@+id/keyboard_toolbar_line"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_below="@id/privacyButton"
        android:layout_marginBottom="5dp"
        android:background="#c0c0c0"/>

    <ImageView
        android:id="@+id/privacyButton"
        android:layout_width="100dp"
        android:layout_alignParentStart="true"
        android:layout_height="35dp"
        android:scaleType="center"
        android:layout_marginStart="30dp"
        android:src="@drawable/research_ic_lock_open_dark" />

    <ImageView
        android:id="@+id/ratingButton"
        android:layout_width="100dp"
        android:layout_alignParentEnd="true"
        android:layout_height="35dp"
        android:scaleType="center"
        android:layout_marginEnd="30dp"
        android:src="@drawable/ic_star" />

</RelativeLayout >

Body:
If I'm not mistaken, this is your solution.

You first put a parent layout and then put the ImageView inside it.
Then onclicklistener on the parent.

 <RelativeLayout  xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/keyboard_toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:orientation="horizontal">

        <View
            android:id="@+id/keyboard_toolbar_line"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_below="@id/privacyButton"
            android:layout_marginBottom="5dp"
            android:background="#c0c0c0"/>

        <RelativeLayout
            android:layout_width="100dp"
            android:layout_height="35dp">
            <ImageView
                android:id="@+id/privacyButton"
                android:layout_width="35dp"
                android:layout_alignParentStart="true"
                android:layout_height="35dp"
                android:scaleType="center"
                android:layout_marginStart="30dp"
                android:src="@drawable/research_ic_lock_open_dark" />
        </RelativeLayout>
    <RelativeLayout
        android:layout_width="100dp"
        android:layout_height="35dp">

        <ImageView
            android:id="@+id/ratingButton"
            android:layout_width="35dp"
            android:layout_alignParentEnd="true"
            android:layout_height="35dp"
            android:scaleType="center"
            android:layout_marginEnd="30dp"
            android:src="@drawable/ic_star" />
    </RelativeLayout>

    </RelativeLayout>


问:
TypeError: Cannot destructure property 'loading' of 'userUpdate' as it is undefined
This is where my variables are defined , i have also attache a detail image of how my variable are used in the second image[][1 i do not understand why it is still claiming that it cannot read property of undefined]</p>

答:
The image you supplied does not show any type of destruction. Assuming variables are defined in the file you provided then you shouldn't see the error you described. However, if you are, for instance, destructuring the properties from props those properties were never passed into the component then that is probably why you are getting that error.

The following destructuring will not work inside your current component if you didn't load those properties into the component.

Now inside your component

{loading, error, success} = props //Nope these properties were never passed to props.

Question: where and how are you using the userUpdate object?


问:
How to handle offscreen EGLContext properly on linux when doing massive rendering task?
Here's my situation, I'm working on a video rendering engine that runs on GPU cloud servers with Ubuntu 16.04 64 bit OS.

The engine listens to user requests, when it receive a rendering request, it will start a thread, create a pbuffer EGLContext, rendering the video frames using opengl calls, encoding frames to a video file, and then destroy the EGLContext. When multiple rendering requests received, rendering engine will start multiple threads and run multiple tasks in parallel. By the way, I set up and destroy EGLContext object using code from this nvidia post.

The thing is, after a lot of rendering tasks, render engine will crash randomly when calling eglCreateContext, it happens for both nVidia cards and ATI cards. And I don't know is it because I'm doing something wrong with EGLContext handling or is it just a bug with Linux EGL driver.

So, instead of create a EGLContext for every rendering task, I reuse previously created EGLConext, and just to make sure to delete all OpenGL resources at the end of every rendering task.

But, I found that even I have deleted all the OpenGL resources(I checked and I checked again), the memory usage will not drop to its initial level after a rendering task is finished. Only after I destroy the EGLContext, the memory will drop the its initial level.

Now, for the first method, have you guys ever encounter such crashing problem? Are the code from the nvidia post the correct way to handle EGLContext? Or should I do something different when it comes to create and destroy EGLContext rapidly.

For the second method, I learned form some posts that event you have called those OpenGL apis to delete your resources, and forced a GPU synchronous using glFinish, EGLContext may still having them in the buffer. And I think this the reason why memory usage does drop after every rendering task if I reuse 'EGLContext'. But is there a way to delete those resources immediately?

答: We end up creating a new process for each rendering task, and things are working great! Thanks to @datenwolf !</p>