Skip to content

fix deleteIndex repeat append namespace#3017

Merged
wu-sheng merged 24 commits intoapache:masterfrom
arugal-docker:master
Jul 11, 2019
Merged

fix deleteIndex repeat append namespace#3017
wu-sheng merged 24 commits intoapache:masterfrom
arugal-docker:master

Conversation

@rainbend
Copy link
Copy Markdown
Member

@rainbend rainbend commented Jul 6, 2019

Please answer these questions before submitting pull request

  • Why submit this pull request?

  • Bug fix

  • New feature provided

  • Improve performance

  • Related issues


Bug fix


New feature or improvement

  • Describe the details and related test reports.

@wu-sheng wu-sheng added this to the 6.3.0 milestone Jul 6, 2019
@wu-sheng wu-sheng added bug Something isn't working and you are sure it's a bug! backend OAP backend related. labels Jul 6, 2019
Copy link
Copy Markdown
Member

@wu-sheng wu-sheng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest you move the whole code block inside ElasticSearchClient as method #deleteTimeSeriesData(modelName, timeBefore). Then the delete codes without formatIndexName could ba placed inside method directly.

List<String> indexes = client.retrievalIndexByAliases(model.getName());

            List<String> prepareDeleteIndexes = new ArrayList<>();
            for (String index : indexes) {
                long timeSeries = TimeSeriesUtils.indexTimeSeries(index);
                if (timeBefore >= timeSeries) {
                    prepareDeleteIndexes.add(index);
                }
            }

            if (indexes.size() == prepareDeleteIndexes.size()) {
                client.createIndex(TimeSeriesUtils.timeSeries(model));
            }

            for (String prepareDeleteIndex : prepareDeleteIndexes) {
                client.deleteIndex(prepareDeleteIndex);
            }

I think don't mixe these two kinds of OP(s) together should be much better.

return deleteIndex(indexName, true);
}

public boolean deleteIndex(String indexName, boolean formatIndexName) throws IOException {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two delete methods will make people very confused.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest you move the whole code block inside ElasticSearchClient as method #deleteTimeSeriesData(modelName, timeBefore). Then the delete codes without formatIndexName could ba placed inside method directly.

List<String> indexes = client.retrievalIndexByAliases(model.getName());

            List<String> prepareDeleteIndexes = new ArrayList<>();
            for (String index : indexes) {
                long timeSeries = TimeSeriesUtils.indexTimeSeries(index);
                if (timeBefore >= timeSeries) {
                    prepareDeleteIndexes.add(index);
                }
            }

            if (indexes.size() == prepareDeleteIndexes.size()) {
                client.createIndex(TimeSeriesUtils.timeSeries(model));
            }

            for (String prepareDeleteIndex : prepareDeleteIndexes) {
                client.deleteIndex(prepareDeleteIndex);
            }

I think don't mixe these two kinds of OP(s) together should be much better.

This code block needs to use TimeSeriesUtils, but TimeSeriesUtils is located in storage-elasticsearch-plugin

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or delete the namespace in the #retrievalIndexByAliasesreturn result.

Copy link
Copy Markdown
Member

@wu-sheng wu-sheng Jul 6, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then build List ESTimeSeriesIndex, in each element, keep namespace and name in two fields. Then add a new delete method accepting ESTimeSeriesIndex

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Copy Markdown
Member

@wu-sheng wu-sheng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adjust tests, please.

return indexName;
}

public String undoFormatIndexName(String indexName) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be private.

}

public String undoFormatIndexName(String indexName) {
if (StringUtils.isNotEmpty(namespace) && indexName.startsWith(namespacePrefix)) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If !startWith(namespace, then you should raise an exception.

@rainbend
Copy link
Copy Markdown
Member Author

rainbend commented Jul 7, 2019

done

Copy link
Copy Markdown
Member

@wu-sheng wu-sheng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Questions for test case

client = new ElasticSearchClient(esAddress, "", "test", "test");
final String esNamespace = System.getProperty("elastic.search.namespace", "");
final String esUser = System.getProperty("elastic.search.user", "test");
final String esPassword = System.getProperty("elastic.search.password", "test");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One question, who will set these properties?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If not, then, namespace feature hasn't been tested.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can I use the maven-failsafe-plugin, as follows

                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-failsafe-plugin</artifactId>
                        <configuration>
                            <systemPropertyVariables>
                                <elastic.search.address>
                                    ${docker.hostname}:${es-port}
                                </elastic.search.address>
                                <elastic.search.namespace>
                                    test
                                </elastic.search.namespace>
                            </systemPropertyVariables>
                        </configuration>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>integration-test</goal>
                                    <goal>verify</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After adding namespace,getIndex has the same problem, which I will modify together

public JsonObject getIndex(String indexName) throws IOException {
indexName = formatIndexName(indexName);
GetIndexRequest request = new GetIndexRequest();
request.indices(indexName);
Response response = client.getLowLevelClient().performRequest(HttpGet.METHOD_NAME, "/" + indexName);
InputStreamReader reader = new InputStreamReader(response.getEntity().getContent());
Gson gson = new Gson();
return gson.fromJson(reader, JsonObject.class);
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

System properties are used for uncertain variables, because of docker env. You don't need this, actually, you could add it to test codes directly, which will be more clear.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, @Arugal #getIndex is not used in codes anymore, we only use it in IT test, let's move it to ITElasticSearchClient? That will make us has fewer codes concern of index name.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, @Arugal #getIndex is not used in codes anymore, we only use it in IT test, let's move it to ITElasticSearchClient? That will make us has fewer codes concern of index name.

#getIndex needs to invoker RestHighLevelClient#getLowLevelClient ,unless we can get a RestHighLevelClient instance via ElasticSearchClient

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

System properties are used for uncertain variables, because of docker env. You don't need this, actually, you could add it to test codes directly, which will be more clear.

done

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, @Arugal #getIndex is not used in codes anymore, we only use it in IT test, let's move it to ITElasticSearchClient? That will make us has fewer codes concern of index name.

#getIndex needs to invoker RestHighLevelClient#getLowLevelClient ,unless we can get a RestHighLevelClient instance via ElasticSearchClient

getIndex method is still there. I think no ine uses it, should remove, right?

Can I do what I said above?

Copy link
Copy Markdown
Member

@wu-sheng wu-sheng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You miss some suggestions from last review.

private JsonObject undoFormatIndexName(JsonObject index) {
if (StringUtils.isNotEmpty(namespace) && index != null && index.size() > 0) {
Set<Map.Entry<String, JsonElement>> entrySet = index.entrySet();
for (Map.Entry<String, JsonElement> entry : entrySet) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change this to index.foreach ->

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

return Collections.EMPTY_LIST;
}

public JsonObject getIndex(String indexName) throws IOException {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getIndex method needs to move to ITElasticSearchClient with undoFormatIndexName(JsonObject index) method.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

public class ITElasticSearchClientOfNamespace extends ITElasticSearchClient {


public ITElasticSearchClientOfNamespace() {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has this run? I haven't used this kind of test before. Please confirm in the log.

Copy link
Copy Markdown
Member Author

@rainbend rainbend Jul 8, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return indexName;
}

private JsonObject undoFormatIndexName(JsonObject index) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need this method, this should move to test class only. Right?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@rainbend rainbend closed this Jul 9, 2019
@rainbend rainbend reopened this Jul 9, 2019
@rainbend
Copy link
Copy Markdown
Member Author

rainbend commented Jul 9, 2019

You miss some suggestions from last review.

Do I have any unfinished suggestions now?

@wu-sheng
Copy link
Copy Markdown
Member

wu-sheng commented Jul 9, 2019

getIndex method is still there. I think no ine uses it, should remove, right?

Copy link
Copy Markdown
Member

@peng-yongsheng peng-yongsheng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not suggest fixed it by this way. You can just add a new delete method without format. It is a very simply way.

@wu-sheng
Copy link
Copy Markdown
Member

wu-sheng commented Jul 9, 2019

@peng-yongsheng If you just want an easy way, please consider putting two good method names. Because time series indexes exist, we can't set these methods as #deleteByIndexName and #deleteByModelName.
In time series case, the model A has indexes including A-20190913,A-20190914, etc., but we can't call #deleteByModelName(A)(I know we don't use in this way). But still, show the API is hard named.

@peng-yongsheng
Copy link
Copy Markdown
Member

@peng-yongsheng If you just want an easy way, please consider putting two good method names. Because time series indexes exist, we can't set these methods as #deleteByIndexName and #deleteByModelName.
In time series case, the model A has indexes including A-20190913,A-20190914, etc., but we can't call #deleteByModelName(A)(I know we don't use in this way). But still, show the API is hard named.

Agree with my two hands.

@rainbend
Copy link
Copy Markdown
Member Author

rainbend commented Jul 9, 2019

@peng-yongsheng If you just want an easy way, please consider putting two good method names. Because time series indexes exist, we can't set these methods as #deleteByIndexName and #deleteByModelName.
In time series case, the model A has indexes including A-20190913,A-20190914, etc., but we can't call #deleteByModelName(A)(I know we don't use in this way). But still, show the API is hard named.

Agree with my two hands.

Now, I only think ElasticSearchTimeSeriesIndex redundant

@wu-sheng
Copy link
Copy Markdown
Member

wu-sheng commented Jul 9, 2019

@peng-yongsheng @dmsolr Then this is my suggestion

  1. Change public boolean deleteIndex(String indexName) throws IOException to public boolean deleteByModelName(String noTimeSeriesMode) throws IOException, also add comment to describe the argument.
  2. Add public boolean deleteByIndexName(String indexName) throws IOException, do delete OP w/o format.

Now, I only think ElasticSearchTimeSeriesIndex redundant

Yes. But basically, we are just talking about naming style.

For getIndex, if you need it in ITTest, add a new method in ITTest.

@peng-yongsheng
Copy link
Copy Markdown
Member

@peng-yongsheng If you just want an easy way, please consider putting two good method names. Because time series indexes exist, we can't set these methods as #deleteByIndexName and #deleteByModelName.
In time series case, the model A has indexes including A-20190913,A-20190914, etc., but we can't call #deleteByModelName(A)(I know we don't use in this way). But still, show the API is hard named.

Agree with my two hands.

Now, I only think ElasticSearchTimeSeriesIndex redundant

Yes, If you use it, it's not the only place that needs it. It is a strategy that how to manage the namespace. Not just for the delete method. So, I do not suggest you use this way. I had thought it at the time of I program the time series implementation. At that time, I had an ideal same as you. But, If we must keep the overall style of the code. I found there are too many codes that need to modify.

@peng-yongsheng
Copy link
Copy Markdown
Member

@peng-yongsheng If you just want an easy way, please consider putting two good method names. Because time series indexes exist, we can't set these methods as #deleteByIndexName and #deleteByModelName.
In time series case, the model A has indexes including A-20190913,A-20190914, etc., but we can't call #deleteByModelName(A)(I know we don't use in this way). But still, show the API is hard named.

Agree with my two hands.

Now, I only think ElasticSearchTimeSeriesIndex redundant

@Arugal
If you interest in how to manage the namespace. I think we can talk about providing a new class named ModelName with at least two attributes. Namespace and model name. And a method to build the final name, and a method to split it. Fixed this PR, think it in the another PR.

@rainbend
Copy link
Copy Markdown
Member Author

rainbend commented Jul 9, 2019

If you interest in how to manage the namespace. I think we can talk about providing a new class named ModelName with at least two attributes. Namespace and model name. And a method to build the final name and a method to split it.

Yes, but wouldn't it be better to know the namespace with less code

Fixed this PR, think it in the another PR.

Do I need to make any modification to this PR

@peng-yongsheng
Copy link
Copy Markdown
Member

peng-yongsheng commented Jul 9, 2019

If you interest in how to manage the namespace. I think we can talk about providing a new class named ModelName with at least two attributes. Namespace and model name. And a method to build the final name and a method to split it.

Yes, but wouldn't it be better to know the namespace with less code

No problem, you can new an issue to discuss it.

Fixed this PR, think it in the another PR.

Do I need to make any modification to this PR

Yes, just provide those two methods, '#deleteByIndexName' and '#deleteByModelName'. Rollback other changed files.

@wu-sheng
Copy link
Copy Markdown
Member

wu-sheng commented Jul 9, 2019

I still recommend to remove getIndex method, only keep it in test case. Don't revert that.

private final String user;
private final String password;
private RestHighLevelClient client;
@Getter(value = AccessLevel.PACKAGE) private RestHighLevelClient client;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use whitebox get from powermock to get this.

@wu-sheng
Copy link
Copy Markdown
Member

/run e2e

wu-sheng
wu-sheng previously approved these changes Jul 10, 2019
Copy link
Copy Markdown
Member

@wu-sheng wu-sheng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. @peng-yongsheng please confirm.

public ElasticSearchClient(String clusterNodes, String namespace, String user, String password) {
this.clusterNodes = clusterNodes;
this.namespace = namespace;
this.namespacePrefix = namespace + "_";
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this.namespacePrefix attribute is no value because we have a common method named formatIndexName.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@wu-sheng
Copy link
Copy Markdown
Member

/run ci

@wu-sheng
Copy link
Copy Markdown
Member

/run e2e

@wu-sheng
Copy link
Copy Markdown
Member

/run ci

@wu-sheng
Copy link
Copy Markdown
Member

ASF jenkins break, we are waiting.

@wu-sheng
Copy link
Copy Markdown
Member

/run ci

@wu-sheng
Copy link
Copy Markdown
Member

/run e2e

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend OAP backend related. bug Something isn't working and you are sure it's a bug!

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants